题目大意:一个10000*10000的舞台,N条有向线,线左边才能布置舞台,求最后舞台面积。(N<=20000)
思路:半平面交模板。
#include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define MN 20000 #define eps 1e-7 struct point{double x,y;point(double x=0,double y=0):x(x),y(y){}}p[MN+5]; point operator+(point a,point b){return point(a.x+b.x,a.y+b.y);} point operator-(point a,point b){return point(a.x-b.x,a.y-b.y);} point operator*(point a,double x){return point(a.x*x,a.y*x);} double operator*(point a,point b){return a.x*b.y-a.y*b.x;} struct line{point p,v;line(double a=0,double b=0,double c=0,double d=0):p(a,b),v(c,d){}}l[MN+5]; bool cmp(line a,line b){return atan2(a.v.y,a.v.x)<atan2(b.v.y,b.v.x);} bool left(line l,point p){return l.v*(p-l.p)<0;} point xp(line a,line b){return a.p+a.v*(b.v*(a.p-b.p)/(a.v*b.v));} int q[MN+5],ql,qr; int main() { int n,i;double ans=0; scanf("%d",&n); for(i=0;i<n;++i) scanf("%lf%lf%lf%lf",&l[i].p.x,&l[i].p.y,&l[i].v.x,&l[i].v.y), l[i].v.x-=l[i].p.x,l[i].v.y-=l[i].p.y; l[n++]=line(0,0,10000,0); l[n++]=line(10000,0,0,10000); l[n++]=line(10000,10000,-10000,0); l[n++]=line(0,10000,0,-10000); sort(l,l+n,cmp); for(i=1;i<n;++i) { while(ql<qr&&left(l[i],p[qr-1]))--qr; while(ql<qr&&left(l[i],p[ql]))++ql; if(q[++qr]=i,fabs(l[q[qr-1]].v*l[i].v)<eps) if(left(l[i],l[q[--qr]].p))q[qr]=i; if(ql<qr)p[qr-1]=xp(l[q[qr]],l[q[qr-1]]); } while(ql<qr&&left(l[q[ql]],p[qr-1]))--qr; p[qr]=xp(l[q[qr]],l[q[ql]]); for(i=ql;++i<qr;)ans+=(p[i]-p[ql])*(p[i+1]-p[ql]); printf("%.1f",ans/2); }