题意:按照顺时针或者逆时针给你一个点集首先要判断是否为凸包,如果为凸包的话,就判断圆能否完全放在这个凸包内
思路:凸包的话叉积跑一边就ok,注意在输入点是记得封口;
判断圆是否在凸包内,首先判断圆心是否在凸包内,然后就简单了;
要注意的一点是先输入半径,再输入的坐标。。。。哥白贡献了一个WA
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define inf 0x7ffffff
using namespace std;
const double eps=1e-10;
const double pi=acos(-1.0);
struct P
{
double x,y;
int index;
P () {}
P (double x,double y):x(x),y(y){
}
P operator -(P p){
return P(x-p.x,y-p.y);
}
P operator +(P p){
return P(x+p.x,y+p.y);
}
P operator *(double d){
return P(x*d,y*d);
}
double det(P p){
return x*p.y-y*p.x;
}
};
P p[1000000],r;
double R;
int n;
double dis;
double dist(P a,P b,P c)
{
double A,B,C;
B=1.0;
A=-((b.y-a.y)/(b.x-a.x));
C=-(A*a.x+a.y);
if(b.x-a.x==0)
{
A=1.0;
B=0.0;
C=-a.x;
}
double mm=fabs(A*c.x+B*c.y+C);
double aaa=sqrt(A*A+B*B);
//printf("\n");
//printf("A== %lf B== %lf C== %lf\n",A,B,C);
return mm/aaa;
}
bool judge1()
{
int k=0;
P q;
q.y=r.y;
q.x=-10000000.0;
for(int i=0;i<n-1;i++)
{
// printf("%lf %lf\n",p[i].x,p[i].y);
// printf("%lf %lf\n",p[i+1].x,p[i+1].y);
if(p[i].y==p[i+1].y)
continue;
if(p[i].y<p[i+1].y)
{
if(p[i].y==r.y)
continue;
}
else
{
if(p[i+1].y==r.y)
continue;
}
if((q-p[i]).det(p[i+1]-p[i])*(r-p[i]).det(p[i+1]-p[i])<=0 && (p[i]-q).det(r-q)*(p[i+1]-r).det(r-q)<=0)
k++;
}
if(k%2==0)
return 0;
return 1;
}
bool judge()
{
if(!judge1())
return 0;
for(int i=0;i<n-1;i++)
{
if(dist(p[i],p[i+1],r)>=R)
continue;
else
return 0;
}
return 1;
}
int main()
{
while(~scanf("%d",&n) && n>=3)
{
int fg=1,fg1=1;
scanf("%lf%lf%lf",&R,&r.x,&r.y);
for(int i=0;i<n;i++)
scanf("%lf%lf",&p[i].x,&p[i].y);
p[n]=p[0];
n++;
dis=(p[1]-p[0]).det(p[2]-p[0]);
for(int i=2;i<n;i++)
{
if(dis*((p[i-1]-p[i-2]).det(p[i]-p[i-2]))<0)
fg=0;
}
if(!fg)
printf("HOLE IS ILL-FORMED\n");
else
{
if(judge())
printf("PEG WILL FIT\n");
else
printf("PEG WILL NOT FIT\n");
}
}
return 0;
}