【CQOI2006】【BZOJ2618】凸多边形

来源:互联网 发布:js div 位置 编辑:程序博客网 时间:2024/05/20 00:50

Description
逆时针给出n个凸多边形的顶点坐标,求它们交的面积。例如n=2时,两个凸多边形如下图:
这里写图片描述

则相交部分的面积为5.233。
Input

第一行有一个整数n,表示凸多边形的个数,以下依次描述各个多边形。第i个多边形的第一行包含一个整数mi,表示多边形的边数,以下mi行每行两个整数,逆时针给出各个顶点的坐标。

Output

输出文件仅包含一个实数,表示相交部分的面积,保留三位小数。

Sample Input
2
6
-2 0
-1 -2
1 -2
2 0
1 2
-1 2
4
0 -3
1 -1
2 2
-1 0
Sample Output
5.233
HINT

100%的数据满足:2<=n<=10,3<=mi<=50,每维坐标为[-1000,1000]内的整数

Source

拆出边半平面交一下然后做凸包求面积.
我并不知道别的做法要怎么做…但是感觉似乎有
看数据范围半平面交不写排序增量暴力就能过
说不定当时重庆考场上就是给的暴力

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#define MAXDBL 1e20#define eps 1e-9#define MAXN 1010using namespace std;int n,m,cnt,num;double ans;struct Point{    double x,y;}s[MAXN],Hull[MAXN];Point operator -(Point a,Point b){    return (Point){a.x-b.x,a.y-b.y};}double operator *(Point a,Point b){    return a.x*b.y-a.y*b.x;}struct line{    Point a,b;    double k;    bool operator <(const line& A)const    {        if (k!=A.k) return k<A.k;        return (b-a)*(A.b-a)>0;    }}que[MAXN],l[MAXN];int head=1,tail;Point get_inter(line A,line B){    double tmp1=(B.b-A.a)*(A.b-A.a),tmp2=(A.b-A.a)*(B.a-A.a);    double t=tmp1/(tmp1+tmp2);    return (Point){B.b.x+t*(B.a.x-B.b.x),B.b.y+t*(B.a.y-B.b.y)};}bool check(line A,line B,line C)//On_right{    Point Inter=get_inter(A,B);    return (C.b-C.a)*(Inter-C.a)<0;}void Calc(){    if (cnt<3)  return;    for (int i=1;i<=cnt;i++)    ans+=Hull[i]*Hull[i+1];    ans=fabs(ans)/2;}int main(){    scanf("%d",&n);    while (n--)    {        scanf("%d",&m);        for (int i=1;i<=m;i++)  scanf("%lf%lf",&s[i].x,&s[i].y);s[m+1]=s[1];        for (int i=1;i<=m;i++)  l[++cnt].a=s[i],l[cnt].b=s[i+1];    }    for (int i=1;i<=cnt;i++)    l[i].k=atan2(l[i].b.y-l[i].a.y,l[i].b.x-l[i].a.x);    sort(l+1,l+cnt+1);    for(int i=1;i<=cnt;i++)    {        if(l[i].k!=l[i-1].k)    num++;        l[num]=l[i];    }    que[++tail]=l[1];que[++tail]=l[2];    for (int i=3;i<=num;i++)    {        while (head<tail&&check(que[tail-1],que[tail],l[i]))    tail--;        while (head<tail&&check(que[head+1],que[head],l[i]))    head++;        que[++tail]=l[i];    }    while (head<tail&&check(que[tail-1],que[tail],que[head]))   tail--;    while (head<tail&&check(que[head+1],que[head],que[tail]))   head++;    que[tail+1]=que[head];cnt=0;    for (int i=head;i<=tail;i++)    Hull[++cnt]=get_inter(que[i],que[i+1]);    Hull[cnt+1]=Hull[1];    Calc();    printf("%.3f",ans);}
0 0
原创粉丝点击