题意:
给出一个n个点的多边形,求多边形核的面积;
多边形的核即为多边形内部的点集,使其中的点可以看到多边形的任意顶点和边;
n<=1500;
题解:
这应该也算是模板题的一种吧;
求多边形核的方法现在是O(nlogn)的;
将所有的直线按极角排序(math库中atan2()函数),然后线性的在双端队列里面搞搞;
这样求出了半平面交的边集,也顺带求出了点集;
求面积的话就直接叉积扫一遍就好了;
但是这道题不一样的地方是没有说顶点按什么序给出;
所以可以先顺时针求一边,如果半平面交无解再逆时针求,都无解那多边形不存在核,答案为0;
半平面交无解就是求出的边集小于三;
为了省事我两次直接粘的代码= =,可以写的函数化一些以缩短码长;
代码:
#include<math.h> #include<stdio.h> #include<string.h> #include<algorithm> #define N 2000 using namespace std; const double EPS=1e-8; const double INF=1e100; struct Point { double x,y; Point(){} Point(double _,double __):x(_),y(__){} void read() { scanf("%lf%lf",&x,&y); } friend Point operator +(Point a,Point b) { return Point(a.x+b.x,a.y+b.y); } friend Point operator -(Point a,Point b) { return Point(a.x-b.x,a.y-b.y); } friend double operator *(Point a,Point b) { return a.x*b.x+a.y*b.y; } friend double operator ^(Point a,Point b) { return a.x*b.y-a.y*b.x; } friend Point operator *(double a,Point b) { return Point(a*b.x,a*b.y); } }Poi[N],p[N]; struct Line { Point p,v; double alpha; Line(){}; Line(Point _,Point __){p=_,v=__-_,alpha=atan2(v.y,v.x);} friend bool operator <(Line a,Line b) { return a.alpha<b.alpha; } friend Point getP(Line a,Line b) { Point u=a.p-b.p; double temp=(b.v^u)/(a.v^b.v); return a.p+temp*a.v; } }l[N],q[N]; int st,en; bool Onleft(Line l,Point a) //严格左侧 { return (l.v^(a-l.p))>EPS; } void HPI(int n) { sort(l+1,l+n+1); q[st=en=1]=l[1]; for(int i=2;i<=n;i++) { while(st<en&&!Onleft(l[i],p[en])) en--; while(st<en&&!Onleft(l[i],p[st+1])) st++; if(fabs(q[en].alpha-l[i].alpha)>EPS) q[++en]=l[i]; else q[en]=Onleft(l[i],q[en].p)?q[en]:l[i]; p[en]=getP(q[en-1],q[en]); } while(st<en&&!Onleft(q[st],p[en])) en--; } int main() { int c,T,n,m,i,j,k; double ans; scanf("%d",&T); for(c=1;c<=T;c++) { scanf("%d",&n); for(i=1;i<=n;i++) Poi[i].read(); for(i=2;i<=n;i++) { l[i]=Line(Poi[i],Poi[i-1]); } l[1]=Line(Poi[1],Poi[n]); HPI(n); p[st]=getP(q[st],q[en]); for(i=st,ans=0;i<en;i++) { ans+=p[i]^p[i+1]; } ans+=p[en]^p[st]; if(ans<0) ans=-ans; if(en-st+1<3) { for(i=2;i<=n;i++) { l[i]=Line(Poi[i-1],Poi[i]); } l[1]=Line(Poi[n],Poi[1]); HPI(n); p[st]=getP(q[st],q[en]); for(i=st,ans=0;i<en;i++) { ans+=p[i]^p[i+1]; } ans+=p[en]^p[st]; if(ans<0) ans=-ans; if(en-st+1<3) ans=0; } printf("%.2lf\n",ans/2+EPS); } return 0; }
原文地址:http://blog.csdn.net/ww140142/article/details/48264311