http://poj.org/problem?id=1584
Test instructions: Clockwise or counter-clockwise point, let you first determine whether the polygon is convex, if not output hole is ill-formed
If yes, determine if a circle of a given size and position can be completely contained
if (OK)
printf ("PEG would fit\n");
Else
printf ("PEG would not fit\n");
1 Turn the dots counterclockwise,
And then the convex,
Then judge whether the center is inside the polygon, and then see if it is included
#include <cstdio> #include <cmath> #include <cstring> #include <string> #include <algorithm&
Gt #include <queue> #include <map> #include <set> #include <vector> #include <iostream> using
namespace Std;
Const double Pi=acos (-1.0);
Double eps=1e-5;
Double tm[5][35]; Double Max (double a,double b) {return a>b?a:b;} double min (double a,double b) {return a<b?a:b;} struct Point {do
Uble x;
Double y;
Point (Double a=0, double b=0) {x=a; y=b;}//constructor};
struct LINESEG {point S;
Point e;
Lineseg (Point A, point B) {s=a; e=b;}
Lineseg () {}};
struct Line//linear analytic equation a*x+b*y+c=0 for a uniform representation, convention a >= 0 {double A;
Double b;
Double C;
Line (double d1=1, double d2=-1, double d3=0) {a=d1; b=d2; c=d3;}
};
Double Multiply (Point sp,point ep,point op) {return (sp.x-op.x) * (EP.Y-OP.Y)-(ep.x-op.x) * (SP.Y-OP.Y));
} double Area_of_polygon (int vcount,point polygon[]) {int i; DoubleS
if (vcount<3) return 0;
s=polygon[0].y* (polygon[vcount-1].x-polygon[1].x);
for (i=1;i<vcount;i++) s+=polygon[i].y* (polygon[(i-1)].x-polygon[(i+1)%vcount].x);
return S/2; }//If the input vertices are in a counter-clockwise order, return true bool Isconterclock (int vcount,point polygon[]) {return Area_of_polygon (Vcount,polygon) >0
;
} void Checkconvex (int vcount,point polygon[],bool bc[]) {int i,index=0;
Point Tp=polygon[0]; for (i=1;i<vcount;i++)//Find first convex vertex {if (polygon[i].y<tp.y| |
(Fabs (POLYGON[I].Y-TP.Y) <eps&&polygon[i].x<tp.x))
{Tp=polygon[i];
Index=i;
}} int count=vcount-1;
Bc[index]=1; while (count)//judgment convexity {if (Multiply (polygon[(index+1)%vcount],polygon[(index+2)%vcount],polygon[index%vcount]) >
=0) bc[(index+1)%vcount]=1;
else bc[(index+1)%vcount]=0;
index++;
count--;
}} bool Isconvex (int vcount,point polygon[]) {bool bc[1005];
Checkconvex (VCOUNT,POLYGON,BC); for (int i=0;i<vcount;i++)//check vertices individually, whether fullThe part is the convex vertex if (!bc[i]) return false;
return true; }/* Find the shortest distance from p to line L and return the point closest to the point on the segment NP Note: NP is the nearest point on the line of the segment L, not necessarily perpendicular */double dist (point p1,point p2)//Return two points Euclidean distance
From {return (sqrt (p1.x-p2.x) * (p1.x-p2.x) + (P1.Y-P2.Y) * (P1.Y-P2.Y));
} double dotmultiply (point p1,point p2,point p0) {return ((p1.x-p0.x) * (p2.x-p0.x) + (P1.Y-P0.Y) * (P2.Y-P0.Y));
} Double relation (point p,lineseg L) {lineseg tl;
TL.S=L.S;
Tl.e=p;
Return dotmultiply (TL.E,L.E,L.S)/(Dist (L.S,L.E) *dist (L.S,L.E));
}//To point C to the line where AB is located perpendicular P point perpendicular (points p,lineseg l) {double r=relation (p,l);
Point TP;
tp.x=l.s.x+r* (l.e.x-l.s.x);
tp.y=l.s.y+r* (L.E.Y-L.S.Y);
return TP;
} double ptolinesegdist (point p,lineseg l,point &np) {double r=relation (p,l);
if (r<0) {np=l.s;
Return Dist (P,L.S);
} if (r>1) {NP=L.E;
Return Dist (P,L.E);
} np=perpendicular (p,l);
Return Dist (P,NP);
}/* Calculates the closest distance from a point to a polyline set and returns the nearest point. Note: the Ptolineseg () function is called */double PtopoiNtset (int vcount,point pointset[],point p,point &q) {int i;
Double cd=double (2147483647), TD;
Lineseg l;
Point Tq,cq;
for (i=0;i<vcount-1;i++) {l.s=pointset[i];
L.E=POINTSET[I+1];
Td=ptolinesegdist (P,L,TQ);
if (TD<CD) {cd=td;
CQ=TQ;
}} Q=cq;
return CD;
}/* Determines whether the circle is within the polygon. Application of Ptolineseg () function 2 */bool Circleinsidepolygon (int vcount,point center,double radius,point polygon[]) {
Point q;
Double D;
q.x=0;
q.y=0;
D=ptopointset (VCOUNT,POLYGON,CENTER,Q); if (d<radius| |
Fabs (D-radius) <eps) return false;
else return true; } bool Online (lineseg L,point p) {return (Fabs (multiply (l.e,p,l.s)) <eps && (((p.x-l.s.x) * (p.x-l.e.x) <=0
) && ((P.Y-L.S.Y) * (P.Y-L.E.Y) <=0)); } bool Intersect (lineseg U,lineseg v) {return ((max (u.s.x,u.e.x) >=min (v.s.x,v.e.x)) && Repulsion Experiment (MAX (v.s.x,v.e.x) >=min (u.s.x,u.e.x)) && (Max (U.S.Y,U.E.Y) >=min (v.s.y,v.e.y) && (Max (V.S.Y,V.E.Y) >=min (U.S.Y,U.E.Y)) && (Multiply (V.S,U.E,U.S) *multiply (U.E,V.E,U.S) >=
0) &&//cross-stand Experiment (multiply (U.S,V.E,V.S) *multiply (V.E,U.E,V.S) >=0)); }//(segment U and v intersect) && return true bool Intersect_a (lineseg u,lineseg v) {return (intersect (U,V)) &
& (!online (U,V.S)) && (!online (U,V.E)) && (!online (V,U.E)) && (!online (V,U.S)));
} int Insidepolygon (int vcount,point polygon[],point q) {int c=0,i,n;
Lineseg L1,l2;
BOOL Bintersect_a,bonline1,bonline2,bonline3;
Double r1,r2;
l1.s=q;
l1.e=q;
L1.e.x=double (2147483647);
N=vcount;
for (i=0;i<vcount;i++) {l2.s=polygon[i];
l2.e=polygon[(i+1)%n]; if (online (l2,q)) return 1; If the dot is on the side, return 1 if ((Bintersect_a=intersect_a (L1,L2)) | | |//INTERSECT and not at the end point ((Bonline1=online (l1,polygon[(i+1)%n)) && The second endpoint is on a ray ((!) (
Bonline2=online (l1,polygon[(i+2)%n])) &&/* Previous endpoint and last endpoint on both sides of Ray */((R1=multiply (polygon[i],polygon[(i+1)%n],l1.s) *multiply (polygon[(i+1)%n],polygon[(i+2)%n],l1.s)) >0) | | (Bonline3=online (l1,polygon[(i+2)%n]) &&/* The next edge is a horizontal line, the previous endpoint and the latter endpoint are on both sides of the ray */((r2=multiply
[(i+2)%n],l1.s) *multiply (polygon[(i+2)%n], polygon[(i+3)%n],l1.s)))) C + +;
} if (c%2 = = 1) return 0;
else return 2;
} point p[1005];
int main () {int i,j,k;
int n;
Double r,x,y;
while (cin>>n>>r>>x>>y) {if (n<3) break;
Double xx,yy;
for (i=0;i<n;i++) {scanf ("%lf%lf", &xx,&yy);
P[i].x=xx;
P[i].y=yy;
} if (Isconterclock (n,p) ==false)//First turn the point set to counter-clockwise {dot TMP;
for (i=0;i<n/2;i++) {tmp=p[i];
P[I]=P[N-I-1];
p[n-i-1]=tmp; }} bool Flag=isconvex (N,P);
Determines if the polygon if (flag) {point q (x, y); BOOL Ok=circleinsidepolygon (N,Q,R,P); Judging whether a circle is included, the method here is to determine whether the minimum value in the distance from the center to each edge is greater than or equal to the radius if (Insidepolygon (n,p,q)!=0)//So you need to first determine if the center is contained
printf ("PEG would not fit\n");
else {if (OK) printf ("PEG would fit\n");
else printf ("PEG would not fit\n");
}} else printf ("HOLE is ill-formed\n");
} return 0; }