POJ 1584 A Round Peg in a Ground Hole

来源:互联网 发布:多益网络 上市 编辑:程序博客网 时间:2024/05/20 06:40

分析:给你n边形的坐标、圆心坐标和半径,问你这n边形是不是凸多边形,如果不是输出:HOLE IS ILL-FORMED,否则,如果圆在凸包内就输出:PEG WILL FIT,否则输出:PEG WILL NOT FIT。因为这n边形的坐标是按顺时针或逆时针给出的,所以判断时只有看每相邻两边的叉积符号是否相同,不同的话就不是凸包。在判断圆心是否在凸包内,这个也好判断,也是看叉积符号是否一致,再判断有没有相交,只要看圆心到直线的距离和半径的比较。

# include <stdio.h># include <math.h>  struct point  {      double x,y;  }v[1005];  double Dot(point a,point b,point c)// ab·ac  {      return (b.x-a.x)*(c.x-a.x)+(b.y-a.y)*(c.y-a.y);  }  double Cross(point a,point b,point c)// abxac  {      return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);  }  double Len(point a,point b)// |ab|  {      return sqrt((b.x-a.x)*(b.x-a.x)+(b.y-a.y)*(b.y-a.y));  }  double Dis(point p,point a,point b)// p到直线ab的距离  {      return fabs(Cross(p,a,b))/Len(a,b);  }  int Convex(int n)// 判断凸包  {      int i;      double f=Cross(v[0],v[1],v[2]);      for(i=1;i<n;i++)        if(f*Cross(v[i],v[(i+1)%n],v[(i+2)%n])<0)          break;      return i<n?0:1;  }  int Contain(point p,int n)// 判断p是否在凸包内  {      int i;      double f=Cross(v[0],v[1],p);      for(i=1;i<n;i++)        if(f*Cross(v[i],v[(i+1)%n],p)<0)          break;      return i<n?0:1;  }  int main()  {      int i,n,f,t=1;      double r;      point p;      while(scanf("%d",&n)!=EOF)      {          if(n<3)            break;          scanf("%lf%lf%lf",&r,&p.x,&p.y);          for(i=0;i<n;i++)            scanf("%lf%lf",&v[i].x,&v[i].y);          if(!Convex(n))            printf("HOLE IS ILL-FORMED\n");          else if(!Contain(p,n))            printf("PEG WILL NOT FIT\n");          else          {              for(i=0;i<n;i++)                if(Dis(p,v[i],v[(i+1)%n])<r)                  break;              if(i<n)                printf("PEG WILL NOT FIT\n");              else                printf("PEG WILL FIT\n");          }      }      return 0;  }


0 0