之前直接套半平面交的板子怎么都过不了
后来看博客说这题精度要求太高要去掉eps什么的。。。但我还是WA
后来随便写一发,直接用A排序就过了
之后纠结半平面交的板子为撒错了
首先吧hpicmp的排序改成用A排序,而不是tan2计算出来的k
后来发现不能把上口封住,会出问题。
而由于没有封口,导致下面的判断首尾合不合法也要去掉
这样才能过。。。计算几何急死人系列,上面是随手写的代码,下面是魔改半平面交的代码
#include<bits/stdc++.h>
#define maxl 50010
#define eps 1e-8
using namespace std;
inline int sgn(double x)
{
if(x>-eps && x<eps) return 0;
if(x>0) return 1;
else return -1;
}
struct point
{
double x,y;
point(double a=0,double b=0)
{
x=a,y=b;
}
point operator + (const point b)const
{
return point(x+b.x,y+b.y);
}
friend point operator * (const double t,const point p)
{
return point(t*p.x,t*p.y);
}
point operator - (const point b)const
{
return point(x-b.x,y-b.y);
}
bool operator == (const point b)const
{
return sgn(x-b.x)==0 && sgn(y-b.y)==0;
}
};
inline double dot(point a,point b)
{
return a.x*b.x+a.y*b.y;
}
inline double det(point a,point b)
{
return a.x*b.y-a.y*b.x;
}
struct line
{// s->e on the left
point s,e;
double k;
line(point a=point(),point b=point())
{
s=a;e=b;
k=atan2(e.y-s.y,e.x-s.x);
}
point operator &(const line b)const
{
double t=det(b.s-s,b.e-b.s);
t=t/det(e-s,b.e-b.s);
return s+t*(e-s);
}
};
struct lne
{
double A,B;int ind;
}a[maxl];
int n,cnt;
point res[maxl];
bool in[maxl];
int ans[maxl];
inline bool cmp(const lne &x,const lne &y)
{
if(sgn(x.A-y.A)==0)
return x.B>y.B;
else
return x.A<y.A;
}
inline void prework()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%lf%lf",&a[i].A,&a[i].B);
a[i].ind=i;
}
sort(a+1,a+1+n,cmp);
}
inline bool onleft(point p,line a)
{
return sgn(det(p-a.s,a.e-a.s))<0;
}
inline void mainwork()
{
cnt=0;
ans[++cnt]=1;res[cnt]=point(0,0);
for(int i=2;i<=n;i++)
{
if(sgn(a[i].A-a[i-1].A)==0)
continue;
line now=line(point(0,a[i].B),point(1,a[i].B+a[i].A));
while(cnt>=2 && !onleft(res[cnt],now))
cnt--;
ans[++cnt]=i;
res[cnt]=line(point(0,a[ans[cnt-1]].B),point(1,a[ans[cnt-1]].B+a[ans[cnt-1]].A)) & now;
}
for(int i=1;i<=cnt;i++)
in[a[ans[i]].ind]=true;
}
inline void print()
{
for(int i=1;i<=n;i++)
if(in[i])
printf("%d ",i);
}
int main()
{
prework();
mainwork();
print();
return 0;
}
#include<bits/stdc++.h>
#define maxl 50010
#define eps 1e-8
using namespace std;
inline int sgn(double x)
{
if(x>-eps && x<eps) return 0;
if(x>0) return 1;
else return -1;
}
struct point
{
double x,y;
point(double a=0,double b=0)
{
x=a,y=b;
}
point operator + (const point b)const
{
return point(x+b.x,y+b.y);
}
friend point operator * (const double t,const point p)
{
return point(t*p.x,t*p.y);
}
point operator - (const point b)const
{
return point(x-b.x,y-b.y);
}
bool operator == (const point b)const
{
return sgn(x-b.x)==0 && sgn(y-b.y)==0;
}
};
inline double dot(point a,point b)
{
return a.x*b.x+a.y*b.y;
}
inline double det(point a,point b)
{
return a.x*b.y-a.y*b.x;
}
struct halfplane
{// s->e on the left
point s,e;int ind;
double k,A,B;
halfplane(point a=point(),point b=point(),int c=0)
{
s=a;e=b;ind=c;
k=atan2(e.y-s.y,e.x-s.x);
}
point operator &(const halfplane &b)const
{
double t=det(b.s-s,b.e-b.s);
t=t/det(e-s,b.e-b.s);
return s+t*(e-s);
}
}a[maxl];
int n,cnt,resn;
point res[maxl*2];
bool in[maxl];
int ans[maxl];
inline void prework()
{
scanf("%d",&n);
double A,B,inf=1ll<<60;point s,e;
for(int i=1;i<=n;i++)
{
scanf("%lf%lf",&A,&B);
a[i-1]=halfplane(point(0,B),point(1,B+A),i);
a[i-1].A=A,a[i-1].B=B;
}
//a[n]=halfplane(point(inf,inf),point(-inf,inf),n+1);
a[n].A=0,a[n].B=inf;
}
inline bool satisfy(point a,const halfplane L)
{
return sgn(det(a-L.s,L.e-L.s))<0;
}
inline bool HPIcmp(const halfplane &a,const halfplane &b)
{
if(sgn(a.A-b.A)==0)
return a.B>b.B;
else
return a.A<b.A;
}
halfplane Q[maxl];
void HPI(halfplane line[],int n,point res[],int &resn)
{
int tot=n;
sort(line,line+n,HPIcmp);
tot=1;
for(int i=1;i<n;i++)
if(sgn(line[i].A-line[i-1].A)!=0)
line[tot++]=line[i];
int head=0,tail=1;
Q[0]=line[0];
Q[1]=line[1];
resn=0;
for(int i=2;i<tot;i++)
{
if(sgn(det(Q[tail].e-Q[tail].s,Q[tail-1].e-Q[tail-1].s))==0||
sgn(det(Q[head].e-Q[head].s,Q[head+1].e-Q[head+1].s))==0)
return;
while(head<tail && !satisfy(Q[tail]&Q[tail-1],line[i]))
tail--;
while(head<tail && !satisfy(Q[head]&Q[head+1],line[i]))
head++;
Q[++tail]=line[i];
}
/* while(head<tail && !satisfy(Q[tail]&Q[tail-1],Q[head]))
tail--;
while(head<tail && !satisfy(Q[head]&Q[head+1],Q[tail]))
head++;*/
for(int i=head;i<=tail;i++)
in[Q[i].ind]=true;
}
inline void mainwork()
{
HPI(a,n,res,resn);
}
inline void print()
{
for(int i=1;i<=n;i++)
if(in[i])
printf("%d ",i);
}
int main()
{
prework();
mainwork();
print();
return 0;
}