bzoj2732: [HNOI2012]射箭 半平面交

这题乍一看与半平面交并没有什么卵联系,然而每个靶子都可以转化为两个半平面。

scanf("%lf%lf%lf",&x,&ymin,&ymax);

于是乎就有ymin<=ax^2+bx<=ymax。(因为抛物线一定经过点(0,0),所以c=0)

考虑前一个有ax^2+bx>=ymin  <=>  ax^2+bx-ymin>=0。

#define A x^2

#define B x

#define C ymin

#define x‘ a

#define y‘ b

于是乎Ax‘+By‘+c>=0

这个式子貌似在哪见过的样子

于是乎上半平面交。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 #define pi (acos(-1.0))
 8 #define maxn 200100
 9 #define double long double
10 const long long inf=1e15;
11 int n,tot,sum;
12
13 double sqr(double x){return x*x;}
14
15 struct point{
16     double x,y;
17 }p[maxn];
18
19 struct line{
20     point from,to;
21     int id;
22     double slope;
23 }l[maxn],q[maxn],a[maxn];
24
25 point operator -(point a,point b){return(point){a.x-b.x,a.y-b.y};}
26 point operator +(point a,point b){return(point){a.x+b.x,a.y+b.y};}
27 double operator *(point a,point b){return a.x*b.y-a.y*b.x;}
28 bool operator ==(line a,line b){return a.slope==b.slope;}
29 bool operator <(line a,line b){
30     return a.slope<b.slope||(a.slope==b.slope && (a.to-a.from)*(b.to-a.from)<0);
31 }
32
33 point getpoint(line a,line b){
34     double t1=(b.to-a.from)*(a.to-a.from),t2=(a.to-a.from)*(b.from-a.from);
35     double t=t1/(t1+t2);
36     return (point){(b.from.x-b.to.x)*t+b.to.x,(b.from.y-b.to.y)*t+b.to.y};
37 }
38
39 bool check(line a,line b,line c){
40     point d=getpoint(a,b);
41     return (c.to-c.from)*(d-c.from)<0;
42 }
43
44 bool bo(int x){
45     int cnt=0;
46     for (int i=1;i<=sum;i++) if (l[i].id<=x) a[++cnt]=l[i];
47     int head=1,tail=2;
48     q[1]=a[1],q[2]=a[2];
49     for (int i=3;i<=cnt;i++){
50         while (head<tail && check(q[tail-1],q[tail],a[i])) tail--;
51         while (head<tail && check(q[head+1],q[head],a[i])) head++;
52         q[++tail]=a[i];
53     }
54     while (head<tail && check(q[tail-1],q[tail],q[head])) tail--;
55     while (head<tail && check(q[head+1],q[head],q[tail])) head++;
56     return tail>head+1;
57 }
58
59 int main(){
60     scanf("%d",&n);
61     l[++tot].to=(point){-inf,inf},l[tot].from=(point){inf,inf};
62     l[++tot].to=(point){inf,inf},l[tot].from=(point){inf,-inf};
63     l[++tot].to=(point){inf,-inf},l[tot].from=(point){-inf,-inf};
64     l[++tot].to=(point){-inf,-inf},l[tot].from=(point){-inf,inf};
65     for (int i=1;i<=n;i++){
66         double x,y1,y2;
67         scanf("%llf%llf%llf",&x,&y1,&y2);
68         double A=sqr(x),B=x,C=-y1;
69         l[++tot].from=(point){-1,(A-C)/B},l[tot].to=(point){1,(-A-C)/B},l[tot].id=i;
70         C=-y2;
71         l[++tot].from=(point){1,(-A-C)/B},l[tot].to=(point){-1,(A-C)/B},l[tot].id=i;
72     }
73
74
75     for (int i=1;i<=tot;i++) l[i].slope=atan2(l[i].to.y-l[i].from.y,l[i].to.x-l[i].from.x);
76     sort(l+1,l+tot+1);
77     sum=unique(l+1,l+tot+1)-l;
78     sum--;
79     int l=1,r=n;
80     while (l<=r){
81         int mid=(l+r)>>1;
82         if (bo(mid)) l=mid+1;
83         else r=mid-1;
84     }
85     printf("%d",r);
86     return 0;
87 }

时间: 2024-10-31 04:17:11

bzoj2732: [HNOI2012]射箭 半平面交的相关文章

bzoj 2732 射箭 半平面交

2732: [HNOI2012]射箭 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2531  Solved: 848[Submit][Status][Discuss] Description 沫沫最近在玩一个二维的射箭游戏,如下图 1 所示,这个游戏中的 x 轴在地面,第一象限中有一些竖直线段作为靶子,任意两个靶子都没有公共部分,也不会接触坐标轴.沫沫控制一个位于(0,0)的弓箭手,可以朝 0 至 90?中的任意角度(不包括 0度和 90度),

BZOJ 2732 HNOI 2012 射箭 半平面交

题目大意:给出一些与x轴垂直的线段,问一个经过原点的抛物线最多能按顺序经过多少条线段. 思路:总体上来说是数学题,我们来推一推. 设这个经过原点的抛物线为y = a * x ^ 2 + b * x,设一条线段的起点和终点为(x0,y1)和(x0,y2),且y2 > y1. 将x0带入到设出的抛物线中,会得到y = a * x0 ^ 2 + b * x0,这时候需要满足的是y <= y2 && y >= y1,也就是a * x0 ^ 2 + b * x0 <= y2

[bzoj2732][HNOI2012]射箭

Description 沫沫最近在玩一个二维的射箭游戏,如下图所示,这个游戏中的$x$轴在地面,第一象限中有一些竖直线段作为靶子,任意两个靶子都没有公共部分,也不会接触坐标轴.沫沫控制一个位于$(0,0)$的弓箭手,可以朝$0$至$90$°中的任意角度(不包括$0$°$,90$°),以任意大小的力量射出带有穿透能力的光之箭.由于游戏中没有空气阻力,并且光之箭没有箭身,箭的轨迹会是一条标准的抛物线,被轨迹穿过的所有靶子都认为被沫沫射中了,包括那些只有端点被射中的靶子.这个游戏有多种模式,其中沫沫最

HDU 2297 半平面交

Run Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 640    Accepted Submission(s): 181 Problem Description Since members of Wuhan University ACM Team are lack of exercise, they plan to particip

关于半平面交

嗯,这是一个很屌的东西.可以把他想象成数学中的线性规划问题,然后自然而然得想到就可以求最优解啦. 如何求解半平面交????? 做法一:暴力枚举点,用该点切割现有的凸多边形,这样的复杂度是O(n^2) 做法二:神奇的分治O(nlogn),然而我并不会.... 做法三:参见2006年朱泽园大神发明的排序增量法:这里就暂时不给详细介绍了. 复杂度O(nlogn),如果把快速排序改成基数排序,复杂度可以进一步降为:O(n)!!!!!! 半平面交的另外一个应用是求多边形的核:可以想象成站在一个多边形的点上

计算几何 半平面交

LA 4992 && hdu 3761 Jungle Outpost 杭电的有点坑啊..一直爆内存,后来发现大白的半平面交模板那里 point *p = new point[n]; line *q = new line[n]这里出了问题,应该是在函数里面申请不了比较大的数组,所以爆内存..我在全局定义了两个数组就不会爆了.. 本来跑了17s多的,后来半平面交sort( l, l + n ) 被我注释了,就跑了9s多,LA上跑了 2s..应该是输入数据比较好,不用按照极角排序..然后就是照着

POJ3525 半平面交

题意:求某凸多边形内部离边界最远的点到边界的距离 首先介绍半平面.半平面交的概念: 半平面:对于一条有向直线,它的方向的左手侧就是它所划定的半平面范围.如图所示: 半平面交:多个半平面的交集.有点类似二元函数的线性规划.如图 求半平面交:用的kuangbin模板= = sol:二分答案 二分距离值,按这个值把边界向内缩,再求新的半平面交.如图: 绿色的是原图形,蓝色是按距离值向里面缩进去之后得到的新图形.对这个新图做半平面交即可. 若半平面交存在,说明与边界的距离是该值的点存在(半平面交里面的点

BZOJ 1137: [POI2009]Wsp 岛屿 半平面交

1137: [POI2009]Wsp 岛屿 Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special JudgeSubmit: 165  Solved: 78[Submit][Status][Discuss] Description Byteotia岛屿是一个凸多边形.城市全都在海岸上.按顺时针编号1到n.任意两个城市之间都有一条笔直的道路相连.道路相交处可以自由穿行.有一些道路被游击队控制了,不能走,但是可以经过这条道路与未被控制的道路的交点.问

bzoj2618[Cqoi2006]凸多边形 半平面交

这是一道半平面交的裸题,第一次写半平面交,就说一说我对半平面交的理解吧. 所谓半平面交,就是求一大堆二元一次不等式的交集,而每个二元一次不等式的解集都可以看成是在一条直线的上方或下方,联系直线的标准方程就可以得出.于是乎这些不等式就可以转化为一些半平面,求的就是半平面交. 而半平面交不可能交出凹多边形(因为凹多边形的定义是有一条边所在的直线能把该多边形分成若干块...YY一下就知道这是不可能的),这是一个十分优美的性质,正类似于凸包(写法也是有些相似的),但半平面交可能交出无界,于是可以加四条类