题意:
半平面交面积
题解:
果断上模板了。
尼玛。。。我输出-0.0给wa了半天,,,抑郁。。。
这个好像没什么用。。。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cstdio> 5 #include <algorithm> 6 #include <cmath> 7 8 #define N 222222 9 #define EPS 1e-10 10 #define SIDE 10000 11 12 using namespace std; 13 14 struct PO 15 { 16 double x,y; 17 void prt() 18 { 19 printf("%lf %lf\n",x,y); 20 } 21 }p[N],o; 22 23 struct LI 24 { 25 PO a,b; 26 double angle; 27 void in(double x1,double y1,double x2,double y2) 28 { 29 a.x=x1; a.y=y1; b.x=x2; b.y=y2; 30 } 31 void prt() 32 { 33 printf("%lf %lf %lf %lf\n",a.x,a.y,b.x,b.y); 34 } 35 }li[N],deq[N]; 36 37 int n,m,cnt; 38 39 inline int dc(double x) 40 { 41 if(x>EPS) return 1; 42 else if(x<-EPS) return -1; 43 return 0; 44 } 45 46 inline PO operator -(PO a,PO b) 47 { 48 PO c; 49 c.x=a.x-b.x; c.y=a.y-b.y; 50 return c; 51 } 52 53 inline double cross(PO a,PO b,PO c) 54 { 55 return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x); 56 } 57 58 inline bool cmp(const LI &a,const LI &b)//极角排序,内侧在前 59 { 60 if(dc(a.angle-b.angle)==0) return dc(cross(a.a,a.b,b.a))<0; 61 return a.angle>b.angle; 62 } 63 64 inline PO getpoint(LI &a,LI &b) 65 { 66 double k1=cross(a.a,b.b,b.a); 67 double k2=cross(a.b,b.a,b.b); 68 PO tmp=a.b-a.a,ans; 69 ans.x=a.a.x+tmp.x*k1/(k1+k2); 70 ans.y=a.a.y+tmp.y*k1/(k1+k2); 71 return ans; 72 } 73 74 inline void read() 75 { 76 for(int i=1;i<=n;i++) 77 { 78 scanf("%lf%lf%lf%lf",&li[i].a.x,&li[i].a.y,&li[i].b.x,&li[i].b.y); 79 li[i].angle=atan2(li[i].b.y-li[i].a.y,li[i].b.x-li[i].a.x); 80 } 81 li[n+1].in(0,0,SIDE,0); 82 li[n+2].in(0,SIDE,0,0); 83 li[n+3].in(SIDE,0,SIDE,SIDE); 84 li[n+4].in(SIDE,SIDE,0,SIDE); 85 for(int i=n+1;i<=n+4;i++) li[i].angle=atan2(li[i].b.y-li[i].a.y,li[i].b.x-li[i].a.x); 86 n+=4; 87 } 88 89 inline void getcut() 90 { 91 sort(li+1,li+1+n,cmp); 92 m=1; 93 for(int i=2;i<=n;i++) 94 if(dc(li[i].angle-li[m].angle)!=0) 95 li[++m]=li[i]; 96 deq[1]=li[1]; deq[2]=li[2]; 97 int bot=1,top=2; 98 for(int i=3;i<=m;i++) 99 { 100 while(bot<top&&dc(cross(li[i].a,li[i].b,getpoint(deq[top],deq[top-1])))<0) top--; 101 while(bot<top&&dc(cross(li[i].a,li[i].b,getpoint(deq[bot],deq[bot+1])))<0) bot++; 102 deq[++top]=li[i]; 103 } 104 while(bot<top&&dc(cross(deq[bot].a,deq[bot].b,getpoint(deq[top],deq[top-1])))<0) top--; 105 while(bot<top&&dc(cross(deq[top].a,deq[top].b,getpoint(deq[bot],deq[bot+1])))<0) bot++; 106 if(bot==top) return; 107 cnt=0; 108 for(int i=bot;i<top;i++) p[++cnt]=getpoint(deq[i],deq[i+1]); 109 if(top-1>bot) p[++cnt]=getpoint(deq[bot],deq[top]); 110 } 111 112 inline double getarea() 113 { 114 double res=0.0; 115 p[cnt+1]=p[1]; 116 for(int i=1;i<=cnt;i++) res+=cross(o,p[i],p[i+1]); 117 return res; 118 } 119 120 inline void go() 121 { 122 getcut(); 123 printf("%.1lf\n",fabs(getarea())*0.5); 124 } 125 126 int main() 127 { 128 while(scanf("%d",&n)!=EOF) read(),go(); 129 return 0; 130 }