首页 > 代码库 > bzoj2618 凸多边形 半平面交

bzoj2618 凸多边形 半平面交

链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2618

题意:求出几个封闭图形围成的内部区域面积。

把每一条边作为有向直线,逆时针遍历全图,左侧的半平面交

技术分享
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 int n,cnt;
 8 const int maxn=55;
 9 struct point
10 {
11     double x,y;
12 }p[maxn],a[maxn*maxn];
13 double operator *(const point &a,const point &b)
14 {
15     return a.x*b.y-a.y*b.x;
16 }
17 point operator -(const point &a,const point &b)
18 {
19     return (point){a.x-b.x,a.y-b.y};
20 }
21 struct line
22 {
23     point a,b;double slop;
24     friend bool operator <(const line &a,const line &b)
25     {
26         if(a.slop!=b.slop)return a.slop<b.slop;
27         return (b.b-a.a)*(a.b-a.a)<0;
28     }
29     void print()
30     {
31         printf("%lf %lf %lf %lf\n",a.x,a.y,b.x,b.y);
32     }
33 }l[maxn*maxn],q[maxn*maxn];
34 void pre()
35 {
36     for(int i=1;i<=cnt;i++)l[i].slop=atan2(l[i].b.y-l[i].a.y,l[i].b.x-l[i].a.x);
37     sort(l+1,l+cnt+1);int tot=0;
38     for(int i=1;i<=cnt;i++)
39     {
40         if(l[i].slop!=l[i-1].slop)tot++;
41         l[tot]=l[i];
42     }
43     cnt=tot;
44 }
45 point inter(line a,line b)
46 {
47     double k1,k2;
48     k1=(a.a-b.a)*(a.a-b.b),k2=(a.b-b.b)*(a.b-b.a);
49     k1=k1/(k1+k2);
50     point ans;
51     ans.x=a.a.x+k1*(a.b.x-a.a.x),ans.y=a.a.y+k1*(a.b.y-a.a.y);
52     return ans;
53 }
54 bool judge(point a,line b)
55 {
56     return (b.a-a)*(b.b-a)<0;
57 }
58 void work()
59 {
60     int L=1,R=0;
61     q[++R]=l[1],q[++R]=l[2];
62     for(int i=3;i<=cnt;i++)
63     {
64         while(L<R&&judge(inter(q[R],q[R-1]),l[i]))R--;
65         while(L<R&&judge(inter(q[L],q[L+1]),l[i]))L++;
66         q[++R]=l[i];
67     }
68     while(L<R&&judge(inter(q[R],q[R-1]),q[L]))R--;
69     cnt=0;
70     for(int i=L;i<R;i++)a[++cnt]=inter(q[i],q[i+1]);
71     a[++cnt]=inter(q[R],q[L]);
72 }
73 void getans()
74 {
75     double ans=0;
76     for(int i=1;i<cnt;i++)ans+=a[i]*a[i+1];
77     ans+=a[cnt]*a[1];
78     ans=fabs(ans/2.0);
79     printf("%0.3lf",ans);
80 }
81 int haha()
82 {
83     scanf("%d",&n);
84     for(int i=1;i<=n;i++)
85     {
86         int m;scanf("%d",&m);
87         for(int j=1;j<=m;j++)
88         {
89             scanf("%lf%lf",&p[j].x,&p[j].y);
90             if(j==1)continue;
91             l[++cnt].a=p[j-1];l[cnt].b=p[j];
92         }
93         l[++cnt].a=p[m];l[cnt].b=p[1];
94     }
95     pre();work();getans();
96 }
97 int sb=haha();
98 int main(){;}
bzoj2618

 

就是所求的结果。

bzoj2618 凸多边形 半平面交