POJ3335(判断多边形内核是否存在)

来源:互联网 发布:2017年网络剧 编辑:程序博客网 时间:2024/05/21 09:07

题目:Rotating Scoreboard

 

题意:题目要求判断多边形内核是否存在,若存在就输出YES,不存在就输出NO,本题和POJ1474一样。本题点的输入顺序是顺时针方向。

/*Goujinping 2013.4.12  NEFUThe masterplate of Polygon kernel.Now the global variable Area stand for the area of Polygon  kernelIn most case,the problem let us judge whether the Polygon kernelexist or not and calculate the area,perimeter,or other constantsabout the Polygon kernel.*/#include <math.h>#include <stdio.h>#include <iostream>#include <algorithm>using namespace std;const int N=11111;const double EPS = 1e-8;typedef double DIY;DIY Area,Length;struct Point{    DIY x,y;    Point() {}    Point(DIY _x,DIY _y):x(_x),y(_y) {}} p[N];Point MakeVector(Point &P,Point &Q){    return Point(Q.x-P.x,Q.y-P.y);}DIY CrossProduct(Point P,Point Q){    return P.x*Q.y-P.y*Q.x;}DIY MultiCross(Point P,Point Q,Point R){    return CrossProduct(MakeVector(Q,P),MakeVector(Q,R));}struct halfPlane{    Point s,t;    DIY angle;    halfPlane() {}    halfPlane(Point _s,Point _t):s(_s),t(_t) {}    halfPlane(DIY sx,DIY sy,DIY tx,DIY ty):s(sx,sy),t(tx,ty) {}    void GetAngle()    {        angle=atan2(t.y-s.y,t.x-s.x);    }} hp[N],q[N];Point IntersectPoint(halfPlane P,halfPlane Q){    DIY a1=CrossProduct(MakeVector(P.s,Q.t),MakeVector(P.s,Q.s));    DIY a2=CrossProduct(MakeVector(P.t,Q.s),MakeVector(P.t,Q.t));    return Point((P.s.x*a2+P.t.x*a1)/(a2+a1),(P.s.y*a2+P.t.y*a1)/(a2+a1));}bool cmp(halfPlane P,halfPlane Q){    if(fabs(P.angle-Q.angle)<EPS)        return MultiCross(P.s,P.t,Q.s)>0;    return P.angle<Q.angle;}bool IsParallel(halfPlane P,halfPlane Q){    return fabs(CrossProduct(MakeVector(P.s,P.t),MakeVector(Q.s,Q.t)))<EPS;}void HalfPlaneIntersect(int n,int &m){    sort(hp,hp+n,cmp);    int i,l=0,r=1;    for(m=i=1; i<n; ++i)        if(hp[i].angle-hp[i-1].angle>EPS) hp[m++]=hp[i];    n=m; m=0;    q[0]=hp[0];q[1]=hp[1];    for(i=2; i<n; i++)    {        if(IsParallel(q[r],q[r-1])||IsParallel(q[l],q[l+1])) return;        while(l<r&&MultiCross(hp[i].s,hp[i].t,IntersectPoint(q[r],q[r-1]))>0) --r;        while(l<r&&MultiCross(hp[i].s,hp[i].t,IntersectPoint(q[l],q[l+1]))>0) ++l;        q[++r]=hp[i];    }    while(l<r&&MultiCross(q[l].s,q[l].t,IntersectPoint(q[r],q[r-1]))>0) --r;    while(l<r&&MultiCross(q[r].s,q[r].t,IntersectPoint(q[l],q[l+1]))>0) ++l;    q[++r]=q[l];    for(i=l; i<r; ++i)        p[m++]=IntersectPoint(q[i],q[i+1]);}void Solve(Point *p,int n,int &m){    int i,j;    p[n]=p[0];    for(i=0;i<n;i++)    {        hp[i]=halfPlane(p[(i+1)%n],p[i]);        hp[i].GetAngle();    }    HalfPlaneIntersect(n,m);}int main(){    int n,m,t;    cin>>t;    while(t--)    {        cin>>n;        for(int i=0; i<n; i++)            cin>>p[i].x>>p[i].y;        Solve(p,n,m);        if(m<3)  puts("NO");        else     puts("YES");    }    return 0;}