Topic link: https: //vjudge.net/problem/POJ-1584
The meaning of problems: first determining the convex hull, and then determines whether or not the polygon circle.
Thinking:
determining the convex hull by using the cross product is determined circle center determines whether the first polygon in the polygon, and then determines the distance to the center of each side is less than the radius. The board is very important! !
AC code:
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<cstdlib> using namespace std; const double eps=1e-8; const double inf=1e20;int sgn(double x){ if(abs(x)<eps) return 0; if(x<0) return -1; return 1; } struct Point{ double x,y; Point(){} Point(double xx,double yy):x(xx),y(yy){} Point operator + (const Point& b)const{ return Point(x+b.x,y+b.y); } Point operator - (const Point& b)const{ return Point(x-b.x,y-b.y); } double operator * (const Point& b)const{ return x*b.x+y*b.y; } double operator^ ( constPoint & B) const { return X * by-BX * y; } // rotation about the origin angle B (radians), the x, y changes void transXY ( Double B) { Double TX = x, TY = y ; X = COS TX * (B) * -TY SiN (B); Y = SiN TX * (B) * TY + COS (B); } }; struct Line { Point S, E; Line () {} Line (Point SS, Point EE) { S = SS, E = EE; } // two lines intersect to find the intersections // first value of 0 indicates a straight overlap of 1 indicates parallel, intersecting represents 2 //When only the first value is 2, the intersection meaningful pair < int , Point> operator & ( const Line B &) const { Point RES = S; IF (SGN ((SE) ^ (BE-BS)) == 0 ) { IF (SGN ((sb.e) ^ (BE-BS)) == 0 ) return the make_pair ( 0 , RES); // overlap the else return the make_pair ( . 1 , RES); // parallel } Double T = ( (sb.s) ^ (BS-BE)) / ((SE) ^ (bs- BE)); res.x+= (e.x-s.x)*t; res.y += (e.y-s.y)*t; return make_pair(2,res); } }; //判断线段相交 bool inter(Line l1,Line l2){ return max(l1.s.x,l1.e.x)>=min(l2.s.x,l2.e.x)&& max(l2.s.x,l2.e.x)>=min(l1.s.x,l1.e.x)&& max(l1.s.y,l1.e.y)>=min(l2.s.y,l2.e.y)&& max(l2.s.y,l2.e.y)>=min(l1.s.y,l1.e.y)&& sgn((l1.s-l2.s)^(l2.e-l2.s))*sgn((l1.e-l2.s)^(l2.e-l2.s))<=0&& sgn((l2.s-l1.s)^(l1.e-l1.s))*sgn((l2.e-l1.s)^(l1.e-l1.s))<=0 ; } Double DIS (Point A, Point B) { return sqrt ((BA) * (BA )); } // Analyzing the segment point BOOL OnSeg (Point P, Line L) { return SGN ((Ls of -P) ^ (Le-P)) == 0 && SGN ((Px -Lsx) * (Px-Lex)) <= 0 && SGN ((Py -Lsy) * (Py-Ley)) <= 0 ; } // determines points within a convex polygon, the complexity O (n-) // points form a convex hull, and counterclockwise order (if the inside of a clockwise <0 to> 0) // point number: ~. 1-n-0 // return value: @ -1: point outside the convex polygon @ 0: convex polygon edge points //1: point in the convex polygon int inConvexPoly (Point A, Point P [], int n-) { for ( int I = 0 ; I <n-; ++ I) IF (SGN ((P [I] -a) ^ (P [(I + . 1 )% n-] -a)) < 0 ) return - . 1 ; the else IF (OnSeg (A, Line (P [I], P [(I + . 1 )% n-]))) return 0 ; return . 1 ; } // determines points within any polygon, the complexity O (n-) // ray method, poly [] is greater than the number of vertexes is equal to 3, the numbers of point 0 ~ n-1, clockwise or counterclockwise sorting // return value @ -1: point on the outer convex polygon //0: point on the boundary of a convex polygon @ 1: point in the convex polygon int inPoly (Point A, Point P [], int n-) { int CNT = 0 ; Line ray, Side; ray.s = A; ray. EY = AY; ray.ex = - INF; for ( int I = 0 ; I <n-; ++ I) { side.s = P [I]; side.e = P [(+ I . 1 )% n-]; IF (OnSeg (A, Side)) return 0 ; IF (SGN (side.sy-side.ey) == 0) Continue ; IF (OnSeg (side.s, ray)) { IF (SGN (side.sy-side.ey)> 0 ) ++ CNT; } the else IF (OnSeg (side.e, ray)) { IF ( SGN (side.ey-side.sy)> 0 ) ++ CNT; } the else IF (Inter (ray, Side)) ++ CNT; } IF (CNT% 2 == . 1 ) return . 1 ; the else return - . 1 ; } // Analyzing convex polygon // allow collinear edges // point may be given a clockwise counterclockwise given // point-n-numbered. 1 ~ 0 BOOL isconvex (poly Point [], int n-) { BOOL S [ . 3 ]; Memset (S, to false , the sizeof (S)); for ( int I = 0 ; I <n-; ++ I) { S [SGN ((poly [(I + . 1 )% n-] -poly [I]) ^ (poly [(I + 2 ) n-%] -poly [I])) + . 1 ] = to true ; IF (S [ 0 ] && S [ 2 ]) return to false ; } return to true ; } // distance between the point of the line segment // return point to the nearest point of the line segment Point NearestPointToLineSeg (Point P, Line L) { Point Result; Double T = ((PL.s) * (Le-Ls of)) / ( (Le-Ls of) * (Le- Ls of)); IF (T> = 0 && T <= . 1 ) { result.x = Lsx + (Lex-Lsx) * T; result.y = + Lsy (Ley-Lsy) * T ; } the else { IF (DIS (P, Ls of) < DIS (P, Le)) return Ls of; the else return Le; } return Result; } int n; double R,X,Y; Point pt[110]; int main(){ while(scanf("%d",&n),n>=3){ scanf("%lf%lf%lf",&R,&X,&Y); for(int i=0;i<n;++i) scanf("%lf%lf",&pt[i].x,&pt[i].y); if(!isconvex(pt,n)){ printf("HOLE IS ILL-FORMED\n"); continue; } Point P=Point(X,Y); if(inPoly(P,pt,n)==-1){ printf("PEG WILL NOT FIT\n"); continue; } int flag=1; for(int i=0;i<n;++i){ if(sgn(dis(P,NearestPointToLineSeg(P,Line(pt[i],pt[(i+1)%n])))-R)<0){ flag=0; break; } } if(flag) printf("PEG WILL FIT\n"); else printf("PEG WILL NOT FIT\n"); } return 0; }