赞
踩
半平面交简化版。
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn=500010;
const double eps=1e-8;
int cmp(double x)
{
if (x>=eps) return 1;
if (fabs(x)<=eps) return 0;
return -1;
}
struct Vector
{
double x,y;
Vector operator + (const Vector &v) const
{
return (Vector){x+v.x,y+v.y};
}
Vector operator - (const Vector &v) const
{
return (Vector){x-v.x,y-v.y};
}
Vector operator * (const double &k) const
{
return (Vector){x*k,y*k};
}
}p[maxn];
typedef Vector Point;
double dot(Vector v,Vector u)
{
return v.x*u.x+v.y*u.y;
}
double cross(Vector v,Vector u)
{
return v.x*u.y-v.y*u.x;
}
struct Line
{
Point p;
Vector v;
int id;
/*double angle() const
{
return atan2(v.y,v.x);
}*/
bool operator < (const Line &l) const
{
return cmp(v.y-l.v.y)==-1;
}
}a[maxn],q[maxn];
Point intersection(Line l,Line m)
{
Vector u=l.p-m.p;
double t=cross(m.v,u)/cross(l.v,m.v);
return l.p+l.v*t;
}
int n,ans[maxn];
int main()
{
//freopen("e.in","r",stdin);
//freopen("e.out","w",stdout);
//freopen("bzoj_1007.in","r",stdin);
//freopen("bzoj_1007.out","w",stdout);
int hd,tl;
double x,y;
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%lf%lf",&x,&y);
a[i]=(Line){(Point){0,y},(Vector){1,x},i};
}
sort(a+1,a+n+1);
q[hd=tl=1]=a[1];
for (int i=2;i<=n;i++)
{
while (hd<tl&&cmp(cross(a[i].v,p[tl-1]-a[i].p))<=0) tl--;
//while (hd<tl&&cmp(cross(a[i].v,p[hd]-a[i].p))<=0) hd++;
if (q[tl]<a[i]) q[++tl]=a[i];
else if (cmp(cross(a[i].v,q[tl].p-a[i].p))<=0) q[tl]=a[i];
if (hd<tl) p[tl-1]=intersection(q[tl-1],q[tl]);
}
//while (hd<tl-1&&cmp(cross(q[1].v,p[tl-1]-q[1].p))<=0) tl--;
for (int i=hd;i<=tl;i++) ans[q[i].id]=1;
for (int i=1;i<=n;i++)
if (ans[i]) printf("%d ",i);
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。