题目大意:有一个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\n",fabs(ans)/2); } }