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 }

 

posted @ 2017-03-02 07:34  ws_ccd  阅读(266)  评论(0编辑  收藏  举报