http://www.lydsy.com/JudgeOnline/problem.php?id=2732

Description

沫沫最近在玩一个二维的射箭游戏,如下图 1 所示,这个游戏中的 x 轴在地面,第一象限中有一些竖直线段作为靶子,任意两个靶子都没有公共部分,也不会接触坐标轴。沫沫控制一个位于(0,0)的弓箭手,可以朝 0 至 90?中的任意角度(不包括 0度和 90度),以任意大小的力量射出带有穿透能力的光之箭。由于游戏中没有空气阻力,并且光之箭没有箭身,箭的轨迹会是一条标准的抛物线,被轨迹穿过的所有靶子都认为被沫沫射中了,包括那些 只有端点被射中的靶子。这个游戏有多种模式,其中沫沫最喜欢的是闯关模式。在闯关模式中,第一关只有一个靶 子,射中这个靶子即可进入第二关,这时在第一关的基础上会出现另外一个靶子,若能够一箭 双雕射中这两个靶子便可进入第三关,这时会出现第三个靶子。依此类推,每过一关都会新出 现一个靶子,在第 K 关必须一箭射中前 K 关出现的所有 K 个靶子才能进入第 K+1 关,否则游戏 结束。沫沫花了很多时间在这个游戏上,却最多只能玩到第七关“七星连珠”,这让她非常困惑。 于是她设法获得了每一关出现的靶子的位置,想让你告诉她,最多能通过多少关

Input

输入文件第一行是一个正整数N,表示一共有N关。接下来有N行,第i+1行是用空格隔开的三个正整数xi,yi1,yi2(yi1<yi2 ),表示第i关出现的靶子的横坐标是xi,纵坐标的范围是从yi1到yi2 。
输入保证30%的数据满足N≤100,50%的数据满足N≤5000,100%的数据满足N≤100000且给 出的所有坐标不超过109 。

Output

仅包含一个整数,表示最多的通关数。
Sample Input

5
2 8 12
5 4 5
3 8 10
6 2 3
1 3 7
Sample Output

3

题解:对于该二次函数我们可以设为

y=ax²+bx

, 所以有

y1<=ax²1+bx1<=y²

化简可得

b>=y1/x1−ax1

同理另半边相同。这样就形成了一个以a,b为未知量的二元一次方程。而题目也就变成了半平面交问题。 通过二分答案, 复杂度就是nlogn的了。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
#include<cmath>
#include<cctype>
#include<cassert>
#include<climits>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define RepD(i,n) for(int i=n;i>=0;i--)
#define MEM(a) memset(a,0,sizeof(a))
#define MEMI(a) memset(a,127,sizeof(a))
#define MEMi(a) memset(a,128,sizeof(a))
#define INF (2139062143)
#define phiF (1000000006)
#define MAXN (1000000+10)#define dou long double
typedef long long ll;
const dou inf=1e15;
int tot,n;
struct Point{dou x,y;Point(){}Point(dou x0,dou y0):x(x0),y(y0){}
};
struct Line{Point s,e;dou k;int id;Line(){}Line(Point s0,Point e0):s(s0),e(e0){}
}l[200005],c[200005],L[200005];dou operator *(Point p1,Point p2){return p1.x*p2.y-p1.y*p2.x;
}
Point operator -(Point p1,Point p2){return Point(p1.x-p2.x,p1.y-p2.y);
}
bool cmp(Line p1,Line p2){if (p1.k==p2.k) return (p2.e-p1.s)*(p1.e-p1.s)>=0;else return p1.k<p2.k;
}
Point inter(Line p1,Line p2){dou k1=(p2.e-p1.s)*(p1.e-p1.s);dou k2=(p1.e-p1.s)*(p2.s-p1.s);dou t=(k2)/(k1+k2);dou x=p2.s.x+(p2.e.x-p2.s.x)*t;dou y=p2.s.y+(p2.e.y-p2.s.y)*t;return Point(x,y);
}
bool jud(Line p1,Line p2,Line p3){Point p=inter(p1,p2);return (p-p3.s)*(p3.e-p3.s)>0;
}bool check(int mid){int Tot(0);For (i,tot){if (l[i].id<=mid) L[++Tot]=l[i];}int cnt(1);Fork (i,2,Tot)if (L[i].k!=L[i-1].k) L[++cnt]=L[i]; int ll=1,rr=2;c[1]=L[1];c[2]=L[2];for (int i=3;i<=Tot;i++){while (ll<rr&&jud(c[rr],c[rr-1],L[i])) rr--;while (ll<rr&&jud(c[ll],c[ll+1],L[i])) ll++;c[++rr]=L[i];} while (ll<rr&&jud(c[rr],c[rr-1],c[ll])) rr--;while (ll<rr&&jud(c[ll],c[ll+1],c[rr])) ll++;if (rr-ll+1<3) return 0;else return 1; }int main(){dou x,y1,y2;scanf("%d",&n);l[++tot].s=Point(-inf,inf);l[tot].e=Point(-inf,-inf);l[++tot].s=Point(-inf,-inf);l[tot].e=Point(inf,-inf);l[++tot].s=Point(inf,-inf);l[tot].e=Point(inf,inf);l[++tot].s=Point(inf,inf);l[tot].e=Point(-inf,inf);For (i,n){scanf("%llf%llf%llf",&x,&y1,&y2);l[++tot].s.x=-1;l[tot].s.y=y1/x-(-1)*x;l[tot].e.x=1;l[tot].e.y=y1/x-x;l[tot].id=i;l[++tot].s.x=1;l[tot].s.y=y2/x-x;l[tot].e.x=-1;l[tot].e.y=y2/x+x;l[tot].id=i;}For (i,tot) l[i].k=atan2(l[i].e.y-l[i].s.y,l[i].e.x-l[i].s.x);sort(l+1,l+1+tot,cmp);int ans(0);for (int lef=1,righ=n;lef<=righ;){int mid=(lef+righ)>>1;if (check(mid)) {ans=mid;lef=mid+1;}else righ=mid-1;}printf("%d",ans);} 

HNOI 2012 射箭 半平面交相关推荐

  1. 【kuangbin专题】计算几何_半平面交

    1.poj3335 Rotating Scoreboard 传送:http://poj.org/problem?id=3335 题意:就是有个球场,球场的形状是个凸多边形,然后观众是坐在多边形的边上的 ...

  2. poj3335 半平面交

    题意:给出一多边形.判断多边形是否存在一点,使得多边形边界上的所有点都能看见该点. sol:在纸上随手画画就可以找出规律:按逆时针顺序连接所有点.然后找出这些line的半平面交. 题中给出的点已经按顺 ...

  3. bzoj 3190 赛车 半平面交

    直接写的裸的半平面交,已经有点背不过模板了... 这题卡精度,要用long double ,esp设1e-20... #include<iostream> #include<cstd ...

  4. BZOJ 1038: [ZJOI2008]瞭望塔 半平面交

    Description 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们 将H村抽象为一维的轮廓.如下图所示 我们可以用一条山的上方轮廓折线(x1 ...

  5. 计算几何学习之半平面交

    首先解决问题:什么是半平面? 顾名思义,半平面就是指平面的一半,我们知道,一条直线可以将平面分为两个部分,那么这两个部分就叫做两个半平面. 然后,半平面怎么表示呢? 二维坐标系下,直线可以表示为ax ...

  6. [BZOJ2033][清橙A1215][2009国家集训队]大灾变-半平面交

    大灾变 Description 艾泽拉斯世界经历一场亘古未有的地震过后,大地和海洋被完全撕裂,旧大陆残缺不全.联盟和部落各种族的居民们被迫离开了世代居住的家园,来寻找新的生存空间.原本平坦的陆地上现在 ...

  7. 【POJ1474】监控摄像头 半平面交

    题目描述 一个著名的仓库管理公司SERKOI 请你为其安装一套闭路监视系统,由于SERKOI 财力有限,每个房间只能安装一台摄像机,不过其镜头可以向任何方向转换. 请你写一个程序,对于给定的房间示意图 ...

  8. [BZOJ1038]ZJOI2008瞭望塔|半平面交

    考虑某个村庄可以被看见的区域,发现一条线段的上方就是可以看见端点的区域,那就把所有线段扔进去做半平面交,不要忘记了要加上两条左右边界..求出来之后发现答案要么是某个村庄往上到半平面交的一段距离,要么是 ...

  9. BZOJ 1829 [Usaco2010 Mar]starc星际争霸 ——半平面交

    发现最终的结果只和$s1$,$s2$,$s3$之间的比例有关. 所以直接令$s3=1$ 然后就变成了两个变量,然后求一次半平面交. 对于每一个询问所属的直线,看看半平面在它的那一侧,或者相交就可以判断 ...

最新文章

  1. Python之os模块用法
  2. 语义分割--Global Deconvolutional Networks for Semantic Segmentation
  3. 从零开始学 Java - Spring 使用 Quartz 任务调度定时器
  4. Java高级补充(Socket服务端、客户端)、Handler类、安卓Socket传数据、WebView
  5. 【DP】【高精】幸运票 (jzoj 2122)
  6. 编译原理 数据流方程_数据科学中最可悲的方程式
  7. memset 和 memcpy 和 memcmp (strncmp遇到\0会中断)
  8. 基于web的通用文本标注工具MarkTool in NLP
  9. vue 使用 ueditor uparse_vue手把手教学~搭建web聊天室
  10. ewebeditor 路径
  11. 超级计算机比赛规则,介绍围棋的规则与玩法
  12. openGL超级宝典第七版
  13. R语言:使用openxlsx读取和写入数据
  14. chrom浏览器flash_flash插件
  15. 【Leetcode刷题Python】134. 加油站
  16. ValueError:only one element tensors can be converted to Python scalars解决办法
  17. 抑制广播风暴 各种发包
  18. 指出下列程序运行的结果()
  19. 记工作的第一月--光说不练,假把式
  20. Cocos Creator发布微信小游戏包内体积过大问题

热门文章

  1. Vue单页面应用的概念以及优缺点
  2. C++通过域名得到IP
  3. Day52_ElasticSearch—目录
  4. 源码学习之EllipsizingTextView
  5. 美团配送数据治理实践【转载美团技术团队博客】
  6. 蒙特卡洛射线追踪的开源项目
  7. mysql rpo是什么意思_揭开数据库RPO等于0的秘密(下)
  8. mac清理存储空间的其他
  9. An Overview of the Tesseract OCR Engine译文
  10. 分式的二阶导数怎么求_二阶导数怎么求?