http://poj.org/problem?id=1584
题意:判断所给的点能不能形成凸包,并判断所给的圆是否在凸包内。
改了好几天的一个题,今天才发现是输入顺序弄错了,办过的最脑残的事情。。sad
1 #include <stdio.h> 2 #include <algorithm> 3 #include <iostream> 4 #include <string.h> 5 #include <math.h> 6 using namespace std; 7 const int N=1002; 8 const double eps=1e-8; 9 double pi=acos(-1.0); 10 int n; 11 struct point 12 { 13 double x,y; 14 point(double x = 0,double y = 0):x(x),y(y) {} 15 double norm()//向量的模 16 { 17 return sqrt(x*x+y*y); 18 } 19 20 }; 21 point operator-(const point &a,const point &b) 22 { 23 return point(a.x-b.x,a.y-b.y); 24 } 25 int cmp(double x)//精度处理 26 { 27 if (fabs(x) < eps) 28 return 0; 29 if (x > 0) 30 return 1; 31 return -1; 32 33 } 34 double det(const point &a,const point &b)//叉乘 35 { 36 return a.x*b.y-a.y*b.x; 37 } 38 39 double dot(const point &a,const point &b)//点乘 40 { 41 return a.x*b.x+a.y*b.y; 42 } 43 44 double dist(const point &a,const point &b)//两点间的距离 45 { 46 return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); 47 } 48 bool PointOnSegment(point p,point s,point t)//判断点是否在线段上 49 { 50 return cmp(det(p-s,t-s))==0&&cmp(dot(p-s,p-t))<=0; 51 } 52 53 double dis_point_segment(const point p,const point s,const point t)//点到线段的距离 54 { 55 if(cmp(dot(p-s,t-s))<0) return (p-s).norm(); 56 if(cmp(dot(p-t,s-t))<0) return (p-t).norm(); 57 return fabs(det(s-p,t-p)/dist(s,t)); 58 } 59 bool is_convex(point *p)//判断凸包 60 { 61 int pre = 0; 62 p[n] = p[0]; 63 p[n+1] = p[1]; 64 for (int i = 2; i <= n; i++) 65 { 66 int dir = cmp(det(p[i-1]-p[i-2],p[i]-p[i-1])); 67 if (!pre) 68 pre = dir; 69 if (pre*dir < 0) return false; 70 } 71 return true; 72 } 73 int point_in(point t,point *ch)//判断点是否在凸包内 74 { 75 int num=0,d1,d2,k; 76 ch[n]=ch[0]; 77 for(int i=0; i<n; i++) 78 { 79 if(PointOnSegment(t,ch[i],ch[i+1])) return 2; 80 k=cmp(det(ch[i+1]-ch[i],t-ch[i])); 81 d1=cmp(ch[i].y-t.y); 82 d2=cmp(ch[i+1].y-t.y); 83 if(k>0&&d1<=0&&d2>0) num++; 84 if(k<0&&d2<=0&&d1>0) num--; 85 } 86 return num!=0; 87 } 88 int main() 89 { 90 double x,y,r; 91 while(~scanf("%d",&n)) 92 { 93 if (n < 3) 94 break; 95 point p[N]; 96 scanf("%lf%lf%lf",&r,&x,&y); 97 point t(x,y); 98 for (int i = 0; i < n; i++) 99 { 100 scanf("%lf%lf",&p[i].x,&p[i].y); 101 } 102 p[n] = p[0];//连接首尾的点 103 if (!is_convex(p)) 104 { 105 printf("HOLE IS ILL-FORMED "); 106 continue; 107 } 108 if(point_in(t,p)) 109 { 110 double Min = dis_point_segment(t,p[0],p[1]); 111 for (int i = 1; i < n; i++) 112 { 113 double dis = dis_point_segment(t,p[i],p[i+1]); 114 Min = min(dis,Min);//圆心到所有线段的最小距离 115 } 116 if (cmp(Min-r)>= 0) 117 printf("PEG WILL FIT "); 118 else 119 printf("PEG WILL NOT FIT "); 120 } 121 else 122 printf("PEG WILL NOT FIT "); 123 124 } 125 return 0; 126 }