题目:How I Mathematician Wonder What You Are!
题意:给一个多边形,判断它是否是星形多边形,星形多边形的定义就是:如果在多边形内部能够找到一点能观察到多边形边上的所有点,那么此多边形就
是星形多边形。
另外重要的一点就是本题点的输入方向是逆时针方向。所以先变为顺时针。
/* Goujinping 2013.4.12 NEFU The masterplate of Polygon kernel. Now the global variable Area stand for the area of Polygon kernel In most case,the problem let us judge whether the Polygon kernel exist or not and calculate the area,perimeter,or other constants about 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; Point temp[N]; while(cin>>n) { if(n==0) break; for(int i=0; i<n; i++) { cin>>temp[i].x>>temp[i].y; p[n-i-1]=temp[i]; } Solve(p,n,m); if(m<3) puts("0"); else puts("1"); } return 0; }