# bzoj 2732 射箭 【抛物线】 【线性规划】 【半平面交】

1、半平面交是否为空R-L>1; 及如果有两个及以上向量，不为空

2、加4个边框注意方向，而且注意让交点在框内，而不是保证大于系数就行

3、题目很坑，要longdouble 而且加上fcmp就错了。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>

#define ll long long
#define inf 1e15
//#define eps 1e-15
#define double long double
#define md
#define N 500010
using namespace std;
struct point { double x,y;};
struct line
{
point a,b;
double slop;
int id;
void init(double x1,double y1,double x2,double y2,int pos)
{
a=(point){x1,y1}; b=(point){x2,y2};
slop=atan2(y2-y1,x2-x1);
id=pos;
}
}l[N],L[N],q[N];
int W=0;
point operator - (point a,point b) { return (point) {a.x-b.x,a.y-b.y};}
double operator * (point a,point b) { return a.x*b.y-a.y*b.x;}
double cmp(line a,line b) { return a.slop==b.slop?(a.b-a.a)*(b.a-a.a)>0:a.slop<b.slop;}
point inter(line a,line b)
{
double k1,k2,t;
k1=(b.b-a.a)*(a.b-a.a);
k2=(a.b-a.a)*(b.a-a.a);
t=k1/(k1+k2);
point ans;
ans.x=b.b.x+(b.a.x-b.b.x)*t;
ans.y=b.b.y+(b.a.y-b.b.y)*t;
return ans;
}

bool jud(line a,line b,line c)
{
point p=inter(a,b);
return (p-c.a)*(c.b-c.a)>0;
}

bool ok(int mid)
{
int cnt=1;
l[1]=L[1];
for (int i=2;i<=W;i++)
{
if (L[i].id>mid) continue;
if (L[i].slop!=L[i-1].slop) cnt++;
l[cnt]=L[i];
}
//printf("mid %d\n",mid);
//for (int i=1;i<=cnt;i++) printf("%d %lf %lf %lf %lf %d\n",i,l[i].a.x,l[i].a.y,l[i].b.x,l[i].b.y,l[i].id);

int L=1,R=2;
q[1]=l[1]; q[2]=l[2];
for (int i=3;i<=cnt;i++)
{
while (L<R&&jud(q[R-1],q[R],l[i])) R--;
while (L<R&&jud(q[L+1],q[L],l[i])) L++;
q[++R]=l[i];
}
while (L<R&&jud(q[R-1],q[R],q[L])) R--;
while (L<R&&jud(q[L+1],q[L],q[R])) L++;
return R-L>1;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("data.in","r",stdin); freopen("data.out","w",stdout);
#endif
int totn;
scanf("%d",&totn);
L[++W].init(-inf,-inf,inf,-inf,0); L[++W].init(inf,-inf,inf,inf,0);
L[++W].init(inf,inf,-inf,inf,0); L[++W].init(-inf,inf,-inf,-inf,0);
for (int i=1;i<=totn;i++)
{
int an,bn,cn;
double x,y1,y2;
scanf("%d%d%d",&an,&bn,&cn);
x=an; y1=bn; y2=cn;
double a=-x,b=y2/x;
L[++W].init(1,a+b,0,b,i);
b=y1/x;
L[++W].init(0,b,1,a+b,i);
}
sort(L+1,L+W+1,cmp);
int l=0,r=totn;
//printf("%d\n",ok(1));
while (l!=r)
{
int mid=(l+r+1)>>1;
if (ok(mid)) l=mid; else r=mid-1;
}
printf("%d\n",l);
return 0;
}


#### BZOJ 2732([HNOI2012]射箭-半平面交)

2013-03-29 14:15:47

#### BZOJ 2732: [HNOI2012]射箭 题解

2017-07-31 20:50:03

#### bzoj 2732 射箭 半平面交 解题报告

2017-08-19 20:32:45

#### [半平面交 随机增量法] BZOJ 2732 [HNOI2012]射箭

2017-02-14 10:40:55

#### bzoj 2732: [HNOI2012]射箭 （二分+半平面交）

2017-01-20 23:22:21

#### 2D射箭抛物线

2017-11-14 16:10:20

#### 弓箭抛物线效果+源码

2012年04月10日 19KB 下载

#### BZOJ 2732: [HNOI2012]射箭

2016-04-08 10:54:25

#### [BZOJ 2732][HNOI 2012]射箭(半平面交)

2015-03-09 20:01:47

#### BZOJ 2732 HNOI 2012 射箭 半平面交

2014-11-26 08:36:46