POJ 1279 Art Gallery(半平面交)

题意:求多边形核的面积;

思路:求所有的核心,再求凸包,在求面积。。。没用半平面交的模版。数据水了。


#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <queue>
#include <stack>
#include <map>
using namespace std;
double const INF = 1e20;
double const EPS = 1e-8;
bool zero(double t){return -EPS<t&&t<EPS;}
struct cvector{
    double x,y;
    cvector(){}
    cvector(double a,double b){x=a,y=b;}
};
cvector operator-(cvector a,cvector b){
    return cvector(a.x-b.x,a.y-b.y);
}
cvector operator+(cvector a,cvector b){
    return cvector(a.x+b.x,a.y+b.y);
}
cvector operator*(double a,cvector b){
    return cvector(a*b.x,a*b.y);
}
double operator*(cvector a,cvector b){
    return a.x*b.x+a.y*b.y;
}
double operator^(cvector a,cvector b){
    return a.x*b.y-b.x*a.y;
}
double length(double t){return t<0?-t:t;}
double length(cvector t){return sqrt(t*t);}
struct cpoint{
    double x,y;
    void get(){scanf("%lf%lf",&x,&y);}
    int operator<(const cpoint t)const {
        return x<t.x||(x==t.x&&y<t.y);
    }
};
cvector operator-(cpoint a,cpoint b){
    return cvector(a.x-b.x,a.y-b.y);
}
double dist(cpoint a,cpoint b){
    return length(a-b);
}
struct segline{
    cpoint a,b;
    segline(cpoint x,cpoint y){a=x,b=y;}
    segline (){}
};
cpoint intersection(segline u,segline v){
    cpoint ret = u.a;
    double t = ((u.a.x-v.a.x)*(v.a.y-v.b.y)-(u.a.y-v.a.y)*(v.a.x-v.b.x))/
                ((u.a.x-u.b.x)*(v.a.y-v.b.y)-(u.a.y-u.b.y)*(v.a.x-v.b.x));
    ret.x+=(u.b.x-u.a.x)*t;
    ret.y+=(u.b.y-u.a.y)*t;
    return ret;
}
int n;
cpoint re[1509];
cpoint tu[1509],tu2[1509];
map<cpoint,int> mp;
int oor1()
{
    int cnt = 0;
    cpoint xx;
    for(int i=0;i<n;i++)
    for(int j=i+1;j<n;j++)
    if(!zero((re[i]-re[i+1])^(re[j]-re[j+1])))
    {
        xx = intersection(segline(re[i],re[i+1]),segline(re[j],re[j+1]));
        int k;
        for(k=0;k<n;k++)
        {
            if(((re[k]-re[k+1])^(xx-re[k+1]))<-EPS) break;
        }
        if(k>=n&&mp.find(xx)==mp.end()) mp[xx] = cnt , tu[cnt++] = xx;
    }
    return cnt;
}
int oor2()
{
    int cnt = 0;
    cpoint xx;
    for(int i=0;i<n;i++)
    for(int j=i+1;j<n;j++)
    if(!zero((re[i]-re[i+1])^(re[j]-re[j+1])))
    {
        xx = intersection(segline(re[i],re[i+1]),segline(re[j],re[j+1]));
        int k;
        for(k=0;k<n;k++)
        {
            if(((re[k]-re[k+1])^(xx-re[k+1]))>EPS) break;
        }
        if(k>=n&&mp.find(xx)==mp.end()) mp[xx] = cnt , tu[cnt++] = xx;
    }
    return cnt;
}
int x_mult(cpoint a,cpoint b,cpoint c){
    return (a.x-c.x)*(b.y-c.y)-(a.y-c.y)*(b.x-c.x);
}
int cmp(const cpoint a,const cpoint b){
    return a.y<b.y||(a.y==b.y&&a.x<b.x);
}
int granham(cpoint p[],int s,cpoint r[])
{
    int i,len,top=1;
    sort(p,p+s,cmp);
   // for(int i=0;i<s;i++) cout<<p[i].x<<" - "<<p[i].y<<endl;
    r[0] = p[0],r[1] = p[1];r[2] = p[2];
    if(s<3) return s;
    for(i=2;i<s;i++){
        while(top&&x_mult(p[i],r[top],r[top-1])>-EPS) top--;
        r[++top] = p[i];
    }
    len = top;r[++top] = p[s-2];
    for(i=s-3;i>=0;i--){
        while(top!=len&&x_mult(p[i],r[top],r[top-1])>-EPS) top--;
        r[++top] = p[i];
    }
    return top;
}
double solve()
{
    mp.clear();
    int cnt = 0;
    cpoint xx;xx.x = 0,xx.y = 0;
    double area=0;
    for(int i=0;i<n;i++)
    area+= (re[i]-re[i+1])^(xx-re[i+1]);
    if(area>0)  cnt = oor1();
    else cnt = oor2();
    if(cnt<3) {
        return 0;
    }
   // for(int i=0;i<cnt;i++)
  //  cout<<tu[i].x<<" "<<tu[i].y<<endl;cout<<endl;

    int tmp = granham(tu,cnt,tu2);

   // for(int i=0;i<tmp;i++)
   // cout<<tu2[i].x<<" "<<tu2[i].y<<endl;
    if(tmp<3) return 0;
    double ret = 0;
    for(int i=0;i<tmp;i++)
    ret+=(tu2[i]-tu2[i+1])^(xx-tu2[i+1]);
    return fabs(ret/2);
}
int main()
{
    freopen("in.txt","r",stdin);
    int cas;
    scanf("%d",&cas);
    while(cas--)
    {
        scanf("%d",&n);
        for(int i=0;i<n;i++) re[i].get();
        re[n] = re[0];
        printf("%.2lf\n",solve());
    }
    return 0;
}


你可能感兴趣的:(POJ 1279 Art Gallery(半平面交))