bzoj 2618: [Cqoi2006]凸多边形
(我以为这道题要求出任意两个凸包的交,然后在容斥呢。。因为我竟然一开始以为万一凸包交出来的不是凸包怎么办。。)
直接把所有边放在一起,半平面交就行。
1 #include<cstdio> 2 #include<algorithm> 3 #include<cmath> 4 #define eps 1e-8 5 using namespace std; 6 inline int ra() 7 { 8 int x=0,f=1; char ch=getchar(); 9 while (ch<'0' || ch>'9'){if (ch=='-') f=-1; ch=getchar();} 10 while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} 11 return x*f; 12 } 13 int n,cnt,tot; 14 double ans; 15 struct point{double x,y;}p[505],a[505]; 16 struct line{point a,b; double angle;} l[505],s[505]; 17 point operator - (point a, point b){ 18 point t; t.x=a.x-b.x; t.y=a.y-b.y; return t; 19 } 20 double operator * (point a, point b){ 21 return a.x*b.y-a.y*b.x; 22 } 23 bool operator < (line a, line b){ 24 if (a.angle==b.angle) return (b.b-a.a)*(a.b-a.a)>0; 25 return a.angle<b.angle; 26 } 27 point intersection(line a, line b) 28 { 29 double k1,k2,t; 30 k1=(b.a-a.a)*(a.b-a.a); 31 k2=(a.b-a.a)*(b.b-a.a); 32 t=k1/(k1+k2); 33 point ans; 34 ans.x=b.a.x+(b.b.x-b.a.x)*t; 35 ans.y=b.a.y+(b.b.y-b.a.y)*t; 36 return ans; 37 } 38 bool jud(line a, line b, line t) 39 { 40 point p=intersection(a,b); 41 //printf("%lf %lf",p.x,p.y); while (1); 42 return (t.a-p)*(t.b-p)<0; 43 } 44 void half_plane_intersection() 45 { 46 sort(l+1,l+cnt+1); 47 int L=1,R=0; 48 for (int i=1; i<=cnt; i++) 49 if (l[i].angle!=l[i-1].angle) l[++tot]=l[i]; 50 cnt=tot; s[++R]=l[1]; s[++R]=l[2]; 51 // for (int i=1; i<=cnt; i++) 52 // printf("%.1lf %.1lf %.1lf %.1lf\n",l[i].a.x,l[i].a.y,l[i].b.x,l[i].b.y); 53 for (int i=3; i<=cnt; i++) 54 { 55 while (L<R && jud(s[R],s[R-1],l[i])) R--; 56 while (L<R && jud(s[L],s[L+1],l[i])) L++; 57 s[++R]=l[i]; 58 } 59 while (L<R && jud(s[R],s[R-1],s[L])) R--; 60 while (L<R && jud(s[L],s[L+1],s[R])) L++; 61 tot=0; 62 s[1+R]=s[L]; 63 for (int i=L; i<=R; i++) 64 a[++tot]=intersection(s[i],s[i+1]); 65 } 66 void get_ans() 67 { 68 if (tot<3) return; 69 a[++tot]=a[1]; 70 for (int i=1; i<tot; i++) 71 ans+=a[i]*a[i+1]; 72 ans=fabs(ans)/2; 73 } 74 int main() 75 { 76 int T=ra(); 77 while (T--) 78 { 79 n=ra(); 80 for (int i=1; i<=n; i++) 81 p[i].x=ra(),p[i].y=ra(); 82 p[n+1]=p[1]; 83 for (int i=1; i<=n; i++) 84 l[++cnt].a=p[i],l[cnt].b=p[i+1]; 85 } 86 for (int i=1; i<=cnt; i++) 87 l[i].angle=atan2(l[i].b.y-l[i].a.y,l[i].b.x-l[i].a.x); 88 half_plane_intersection(); 89 get_ans(); 90 printf("%.3lf",ans); 91 return 0; 92 }