题目:
题意:
给出一个半径R、一个点O、顺时针或者逆时针给出一个多边形
首先判断多边形是否为凸多边形,如果不是输出HOLE IS ILL-FORMED
然后再判断以O为圆心以R为半径的圆是否完全在多边形里,是则输出PEG WILL FIT,否则输出PEG WILL NOT FIT
题解:
这个判断是否为凸多边形的话,考虑ta们的特点:任取一条边, 整个图形都在这条边所在直线的一侧.
这个圆呢?用射线法看看圆心O在不在多边形里,然后顺便计算disTL满足条件就好(点到线的距离)
—–图截选自Enzymii
1A啦
代码:
#include <cstdio>
#include <cmath>
using namespace std;
const double eps=1e-9;
int n;
int dcmp(double x)
{
if (x<=eps && x>=-eps) return 0;
return (x>0)?1:-1;
}
struct po
{
double x,y;
po(double X=0,double Y=0){x=X;y=Y;}
}dian[100005];
po operator -(po x,po y){return po(x.x-y.x,x.y-y.y);}
double cj(po x,po y){return x.x*y.y-x.y*y.x;}
double dot(po x,po y){return x.x*y.x+x.y*y.y;}
double len(po x){return sqrt(dot(x,x));}
double disTL(po p,po a,po b)
{
po v=b-a,w=p-a;
return fabs(cj(v,w)/len(v));
}
bool PInP(po p,double R)
{
int cnt=0,a,b,c;
for (int i=1;i<=n;i++)
{
if (dcmp(disTL(p,dian[i],dian[i%n+1])-R)<0) return 0;
a=dcmp(cj(dian[i%n+1]-dian[i],p-dian[i]));
b=dcmp(dian[i].y-p.y);
c=dcmp(dian[i%n+1].y-p.y);
if (a>0 && b<=0 && c>0) ++cnt;
if (a<0 && b>0 && c<=0) --cnt;
}
if (cnt) return 1;
return 0;
}
int main()
{
while (scanf("%d",&n) && n>=3)
{
double r,x,y;bool fff=1;po p;
scanf("%lf%lf%lf",&r,&x,&y),p=po(x,y);
for (int i=1;i<=n;i++) scanf("%lf%lf",&x,&y),dian[i]=po(x,y);
int fx=0;
for (int i=1;i<n;i++)
{
int t=dcmp(cj(dian[i%n+1]-dian[i],dian[(i+1)%n+1]-dian[i]));
if (t)
{
if (!fx) fx=t;else if (fx!=t) {fff=0;break;}
}
}
if (!fff) printf("HOLE IS ILL-FORMED\n");
else
{
if (!PInP(p,r)) printf("PEG WILL NOT FIT\n");
else printf("PEG WILL FIT\n");
}
}
}