[POJ]1279: Art Gallery

题目大意:有一个N边形展馆,问展馆内有多少地方可以看到所有墙壁。(N<=1500)

思路:模板题,半平面交求出多边形的核后计算核的面积。

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
inline int read()
{
    int x,f=1;char c;
    while((c=getchar())<'0'||c>'9')if(c=='-')f=0;
    for(x=c-'0';(c=getchar())>='0'&&c<='9';)x=(x<<3)+(x<<1)+c-'0';
    return f?x:-x;
}
#define MN 1500
#define eps 1e-7
struct P{double x,y;}p[MN+5];
P operator+(P a,P b){return (P){a.x+b.x,a.y+b.y};}
P operator-(P a,P b){return (P){a.x-b.x,a.y-b.y};}
P operator*(P a,double x){return (P){a.x*x,a.y*x};}
double operator*(P a,P b){return a.x*b.y-a.y*b.x;}
struct line{P p,v;}l[MN+5];
bool cmp(line a,line b){return atan2(a.v.y,a.v.x)<atan2(b.v.y,b.v.x);}
int q[MN+5],ql,qr;
bool left(line l,P p){return l.v*(p-l.p)>0;}
P xp(line a,line b){return a.p+a.v*(b.v*(a.p-b.p)/(a.v*b.v));}
int main()
{
    int T=read(),n,i;double ans;
    while(T--)
    {
        n=read();
        for(i=0;i<n;++i)p[i].x=read(),p[i].y=read();
        for(p[n]=p[i=0];i<n;++i)l[i].p=p[i+1],l[i].v=p[i]-p[i+1];
        sort(l,l+n,cmp);
        for(q[ql=qr=0]=0,i=1;i<n;++i)
        {
            while(ql<qr&&!left(l[i],p[qr-1]))--qr;
            while(ql<qr&&!left(l[i],p[ql]))++ql;
            if(q[++qr]=i,fabs(l[q[qr]].v*l[q[qr-1]].v)<eps)
                if(left(l[q[--qr]],l[i].p))q[qr]=i;
            if(ql<qr)p[qr-1]=xp(l[q[qr-1]],l[q[qr]]);
        }
        while(ql<qr&&!left(l[q[ql]],p[qr-1]))--qr;
        p[qr]=xp(l[q[qr]],l[q[ql]]);
        for(ans=0,i=ql;++i<qr;)ans+=(p[i]-p[ql])*(p[i+1]-p[ql]);
        printf("%.2f
",fabs(ans)/2);
    }
}
原文地址:https://www.cnblogs.com/ditoly/p/POJ1279.html