Grandpa's Estate
题意:有一个绳子和许多钉子,绳子围着钉子组成凸边形,现在绳子和一些钉子都没了,问这些钉子通过加点能否唯一确定一个凸边形
思路:一开始以为是判断这些点能否组成一个凸边形。。完全理解错误。。原来是判断这是不是一个稳定凸包,就是一个边上有>=3的点,这样外部就不能再加点使其变成凸包,然而一个边上只有两个点的话,就可以再外部再增加点变成凸包,就是不稳定的,只要先求出凸包,这里包括三点共线的,也要把点加入其中,然后判断每条边的点数是否>=3即可,由于凸包三条边,每条边至少三个点,因此当顶点数<6时,是不满足的
1 // 2 // Created by HJYL on 2020/2/2. 3 // 4 #include<iostream> 5 #include<cstring> 6 #include<cstdio> 7 #include<cmath> 8 #include<algorithm> 9 using namespace std; 10 const double eps=1e-8; 11 const int maxn=1000+100; 12 13 struct Point{ 14 double x,y; 15 Point(double x = 0, double y = 0) : x(x), y(y) {} 16 Point operator-(Point const &B) const { 17 return Point(x - B.x, y - B.y); 18 } 19 bool operator<(Point const &C)const{ 20 if(x==C.x) 21 return y<C.y; 22 return x<C.x; 23 } 24 }p[maxn],ch[maxn]; 25 26 int sgn(double x){ 27 if(abs(x)<eps) return 0; 28 else return x<0?-1:1; 29 } 30 typedef Point Vector; 31 32 double Cross(Point A,Point B) 33 { 34 return A.x*B.y-A.y*B.x; 35 } 36 37 double Multi(Point p1,Point p2, Point p3) 38 { 39 return (p2.x - p1.x) * (p3.y - p1.y) - (p2.y - p1.y) * (p3.x - p1.x); 40 } 41 42 bool same(Point A,Point B,Point C) 43 { 44 int x=sgn(Multi(A,B,C)); 45 if(x==0) 46 return true; 47 else 48 return false; 49 } 50 int n; 51 int ConvexHull() ///**求凸包*/ 52 { 53 sort(p,p+n);//n顶点数 54 int m = 0; 55 for(int i = 0; i < n; i++) 56 { 57 while(m > 1 && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2]) <= 0) m--; 58 ch[m++] = p[i]; 59 } 60 int k = m; 61 for(int i = n-2; i >= 0; i--) 62 { 63 while(m > k && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2]) <= 0) m--; 64 ch[m++] = p[i]; 65 } 66 if(n > 1) m--; 67 return m; 68 } 69 int judge(Point a,Point b)//判断凸包一条边上是否有3个以上的点(含端点) 70 { 71 int i,num=0; 72 for(i=0;i<n;i++) 73 { 74 if(Cross(a-p[i],p[i]-b)==0)num++; 75 } 76 if(num>=3)return 1; 77 return 0; 78 } 79 int main() 80 { 81 int T; 82 scanf("%d",&T); 83 while(T--) { 84 scanf("%d", &n); 85 for (int i = 0; i < n; i++) 86 scanf("%lf%lf", &p[i].x, &p[i].y); 87 if (n < 6) { 88 printf("NO "); 89 continue; 90 } 91 int mm=ConvexHull(); 92 bool flag = false; 93 for(int i=1;i<mm;i++) 94 { 95 if(!judge(ch[i],ch[i-1])) 96 { 97 flag=true; 98 break; 99 } 100 } 101 if(flag) 102 printf("NO "); 103 else 104 printf("YES "); 105 } 106 return 0; 107 }