poj1584 A Round Peg in a Ground Hole

来源:互联网 发布:思迅商云8软件好不好 编辑:程序博客网 时间:2024/06/06 19:39

自我感觉这道题难的是题意,别的其实不难!当时看到这道题,看了一遍,觉得难懂,然后就做下面的题了,然后又回过头来看题还是一知半解,然后看了别人的翻译的大致题意,结果还是错理解了,题中是允许多点共线的!

大致思路:首先对于所给的洞的点,判断是否是凸多边形,图形的输入和输出可以是顺时针或者逆时针,而且允许多点共线,这点让我WA了一次!

判断是凸多边形后,判断所给的圆心是否在多边形内,然后判断圆心到各边的距离是否大于半径,以此就可以得到结果了!

 #include<iostream>//注意是允许有共线的情况的#include<cmath>#include<cstdio>using namespace std;#define exp 0.0000000001typedef struct point {double x,y;}rr;point a[10000],b;double radius,pegx,pegy;int n;double multipy(point p1,point p2,point p3,point p4){double s=(p2.x-p1.x)*(p4.y-p3.y)-(p2.y-p1.y)*(p4.x-p3.x);return s;}double dis(point p1,point p2){if(fabs(p1.x-p2.x)<exp)//相等的{return fabs(p2.x-pegx);}else{double k=(p2.y-p1.y)/(p2.x-p1.x);double b=p2.y-k*p2.x;return fabs(k*pegx-pegy+b)/sqrt(k*k+1);//返回的是距离的}}int main(){while(true){scanf("%d",&n);int i;if(n<3)break;scanf("%lf%lf%lf",&radius,&pegx,&pegy);for(i=0; i<n; i++)scanf("%lf%lf",&a[i].x,&a[i].y);a[n].x=a[0].x;a[n].y=a[0].y;a[1+n].x=a[1].x;a[n+1].y=a[1].y;//要对所有的角都进行测试的int sign=0;i=3;int t=0;//表死有三点共线的情况的for(i=3; i<=n+1; i++){   if(multipy(a[i-2],a[i-1],a[i-1],a[i])>exp)//首先第一个测试,是判定给出的点是顺时针给的还是逆时针给的   {   t=1;//正的   break;   }       if(multipy(a[i-2],a[i-1],a[i-1],a[i])<-exp)   {t=2;//负的break;   }}if(t!=0){for(;i<=n+1; i++){if((t==1 && multipy(a[i-2],a[i-1],a[i-1],a[i])<-exp) || (t==2 && multipy(a[i-2],a[i-1],a[i-1],a[i])>exp))//在逆时针的地方,就是错的{sign=1;break;}}}if(sign==1 || t==0)printf("HOLE IS ILL-FORMED\n");else{//先判断是否在内部的b.x=pegx;b.y=pegy;for(i=1; i<=n; i++)if((t==1 && multipy(a[i-1],a[i],a[i],b)<=exp) || (t==2 && multipy(a[i-1],a[i],a[i],b)>=-exp)){sign=1;break;}if(sign==0){for(i=0; i<n; i++){double len=dis(a[i],a[i+1]);if(len<radius)//小于0{sign=1;//即不能发下钉子的break;}}}if(sign==1)printf("PEG WILL NOT FIT\n");elseprintf("PEG WILL FIT\n");}}return 0;}


 

原创粉丝点击