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

就是所求的结果。

时间: 2024-08-13 11:07:23

bzoj2618 凸多边形 半平面交的相关文章

【bzoj2618】[Cqoi2006]凸多边形 半平面交

题目描述 逆时针给出n个凸多边形的顶点坐标,求它们交的面积.例如n=2时,两个凸多边形如下图: 则相交部分的面积为5.233. 输入 第一行有一个整数n,表示凸多边形的个数,以下依次描述各个多边形.第i个多边形的第一行包含一个整数mi,表示多边形的边数,以下mi行每行两个整数,逆时针给出各个顶点的坐标. 输出 输出文件仅包含一个实数,表示相交部分的面积,保留三位小数. 样例输入 2 6 -2 0 -1 -2 1 -2 2 0 1 2 -1 2 4 0 -3 1 -1 2 2 -1 0 样例输出

bzoj2618[Cqoi2006]凸多边形 半平面交

这是一道半平面交的裸题,第一次写半平面交,就说一说我对半平面交的理解吧. 所谓半平面交,就是求一大堆二元一次不等式的交集,而每个二元一次不等式的解集都可以看成是在一条直线的上方或下方,联系直线的标准方程就可以得出.于是乎这些不等式就可以转化为一些半平面,求的就是半平面交. 而半平面交不可能交出凹多边形(因为凹多边形的定义是有一条边所在的直线能把该多边形分成若干块...YY一下就知道这是不可能的),这是一个十分优美的性质,正类似于凸包(写法也是有些相似的),但半平面交可能交出无界,于是可以加四条类

BZOJ 2618 CQOI2006 凸多边形 半平面交

题目大意:给定n个凸多边形,求交集的面积 时隔多年我终于把完整的半平面交搞出来了--真尼玛艰辛-- 曾经写了一发 RE到死 于是就搁置0.0 今天写一发又是WA到死的节奏-- 不多说直接上代码 其实刘汝佳同学写麻烦了 每次插入一个半平面之后不用两端都删的 只删一端 最后再处理两端的部分就行 300题留念--切了道模板题也不错 #include <cmath> #include <cstdio> #include <cstring> #include <iostre

BZOJ 2618 CQOI 2006 凸多边形 半平面交

题目大意:给出n个凸多边形,求这些多边形的面积的交. 思路:犯傻了..以后看到凸多边形第一时间就要想到半平面交啊..多明显啊,半天愣着没想出来. CODE: #include <cmath> #include <cstdio> #include <iomanip> #include <cstring> #include <iostream> #include <algorithm> #define MAX 6100 #define E

关于半平面交

嗯,这是一个很屌的东西.可以把他想象成数学中的线性规划问题,然后自然而然得想到就可以求最优解啦. 如何求解半平面交????? 做法一:暴力枚举点,用该点切割现有的凸多边形,这样的复杂度是O(n^2) 做法二:神奇的分治O(nlogn),然而我并不会.... 做法三:参见2006年朱泽园大神发明的排序增量法:这里就暂时不给详细介绍了. 复杂度O(nlogn),如果把快速排序改成基数排序,复杂度可以进一步降为:O(n)!!!!!! 半平面交的另外一个应用是求多边形的核:可以想象成站在一个多边形的点上

POJ3525 半平面交

题意:求某凸多边形内部离边界最远的点到边界的距离 首先介绍半平面.半平面交的概念: 半平面:对于一条有向直线,它的方向的左手侧就是它所划定的半平面范围.如图所示: 半平面交:多个半平面的交集.有点类似二元函数的线性规划.如图 求半平面交:用的kuangbin模板= = sol:二分答案 二分距离值,按这个值把边界向内缩,再求新的半平面交.如图: 绿色的是原图形,蓝色是按距离值向里面缩进去之后得到的新图形.对这个新图做半平面交即可. 若半平面交存在,说明与边界的距离是该值的点存在(半平面交里面的点

BZOJ 1137: [POI2009]Wsp 岛屿 半平面交

1137: [POI2009]Wsp 岛屿 Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special JudgeSubmit: 165  Solved: 78[Submit][Status][Discuss] Description Byteotia岛屿是一个凸多边形.城市全都在海岸上.按顺时针编号1到n.任意两个城市之间都有一条笔直的道路相连.道路相交处可以自由穿行.有一些道路被游击队控制了,不能走,但是可以经过这条道路与未被控制的道路的交点.问

HDU 2297 半平面交

Run Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 640    Accepted Submission(s): 181 Problem Description Since members of Wuhan University ACM Team are lack of exercise, they plan to particip

计算几何 半平面交

LA 4992 && hdu 3761 Jungle Outpost 杭电的有点坑啊..一直爆内存,后来发现大白的半平面交模板那里 point *p = new point[n]; line *q = new line[n]这里出了问题,应该是在函数里面申请不了比较大的数组,所以爆内存..我在全局定义了两个数组就不会爆了.. 本来跑了17s多的,后来半平面交sort( l, l + n ) 被我注释了,就跑了9s多,LA上跑了 2s..应该是输入数据比较好,不用按照极角排序..然后就是照着