bzoj2618[Cqoi2006]凸多边形
半平面交。
抄一份代码de一下午bug。
抄板选手的日常。
1 //Achen 2 #include<algorithm> 3 #include<iostream> 4 #include<cstring> 5 #include<cstdlib> 6 #include<vector> 7 #include<cstdio> 8 #include<queue> 9 #include<cmath> 10 typedef double db; 11 typedef long long LL; 12 using namespace std; 13 const int N=5e4+7; 14 const db eps=1e-10; 15 int n,k,cnt,tot; 16 17 template<typename T>void read(T &x) { 18 char ch=getchar(); x=0; T f=1; 19 while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar(); 20 if(ch=='-') f=-1,ch=getchar(); 21 for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f; 22 } 23 24 struct pt { 25 db x,y; 26 pt(){} 27 pt(db x,db y):x(x),y(y){} 28 }p[N]; 29 30 pt operator + (pt A,pt B) { return pt(A.x+B.x,A.y+B.y); } 31 pt operator - (pt A,pt B) { return pt(A.x-B.x,A.y-B.y); } 32 pt operator * (pt A,db p) { return pt(A.x*p,A.y*p); } 33 pt operator / (pt A,db p) { return pt(A.x/p,A.y/p); } 34 db dot(pt A,pt B) { return A.x*B.x+A.y*B.y; } 35 db cross(pt A,pt B) { return A.x*B.y-A.y*B.x; } 36 db length(pt A) { return sqrt(dot(A,A)); } 37 db dcmp(db x) { return (fabs(x)<eps)?0:(x<0?-1:1); } 38 39 struct Line { 40 pt a,b; 41 db slop; 42 friend bool operator <(const Line&A,const Line&B) { 43 return (A.slop<B.slop)||(A.slop==B.slop&&cross(A.b-A.a,B.b-A.a)<0); 44 } 45 }L[N],a[N]; 46 47 db get_Area(int n) { 48 if(n<3) return 0; 49 db res=0; p[n+1]=p[1]; 50 for(int i=1;i<=n;i++) res+=cross(p[i],p[i+1]); 51 return fabs(res)/2.0; 52 } 53 54 pt inter(Line A,Line B) { 55 pt rs; 56 db k1=cross(B.b-A.a,A.b-A.a); 57 db k2=cross(A.b-A.a,B.a-A.a); 58 db t=k1/(k1+k2); 59 rs.x=B.b.x+(B.a.x-B.b.x)*t; 60 rs.y=B.b.y+(B.a.y-B.b.y)*t; 61 return rs; 62 } 63 64 int ck(Line A,Line B,Line P) { 65 pt t=inter(A,B); 66 return cross(t-P.a,P.b-P.a)>0; 67 } 68 69 db solve(int n) { 70 sort(L+1,L+n+1); 71 for(int i=1;i<=n;i++) 72 if(i==1||L[i].slop!=L[i-1].slop) a[++tot]=L[i]; 73 cnt=0; int ql=1,qr=0; 74 L[++qr]=a[1]; L[++qr]=a[2]; 75 for(int i=3;i<=tot;i++) { 76 while(qr>ql&&ck(L[qr-1],L[qr],a[i])) qr--; 77 while(qr>ql&&ck(L[ql+1],L[ql],a[i])) ql++; 78 L[++qr]=a[i]; 79 } 80 while(qr>ql&&ck(L[qr-1],L[qr],L[ql])) qr--; 81 while(qr>ql&&ck(L[ql+1],L[ql],L[qr])) ql++; 82 L[qr+1]=L[ql]; 83 for(int i=ql;i<=qr;i++) 84 p[++cnt]=inter(L[i],L[i+1]); 85 return get_Area(cnt); 86 } 87 88 int main() { 89 #ifdef DEBUG 90 freopen(".in","r",stdin); 91 freopen(".out","w",stdout); 92 #endif 93 read(n); 94 while(n--) { 95 read(k); 96 for(int i=1;i<=k;i++) { 97 read(p[i].x); read(p[i].y); 98 } 99 p[k+1]=p[1]; 100 for(int i=1;i<=k;i++) { 101 L[++cnt].a=p[i]; L[cnt].b=p[i+1]; 102 L[cnt].slop=atan2(L[cnt].b.y-L[cnt].a.y,L[cnt].b.x-L[cnt].a.x); 103 } 104 } 105 printf("%.3lf\n",solve(cnt)); 106 return 0; 107 } 108 /* 109 2 110 6 111 -2 0 112 -1 -2 113 1 -2 114 2 0 115 1 2 116 -1 2 117 4 118 0 -3 119 1 -1 120 2 2 121 -1 0 122 */