pku 1228 Grandpa's Estate .cpp
题意:一个凸包丢失了一些点后,问是否可以用剩下的这些点唯一确定以前的凸包。
解法:先求出这些点的凸包,然后判断每条边上是否至少有3个点(含顶点),如果有,那么可以唯一确定以前的凸包。
View Code
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <iostream> 5 #include <algorithm> 6 #include <queue> 7 #include <vector> 8 #include <math.h> 9 #define INF 0x7fffffff 10 #define eps 1e-8 11 #define N 6 12 using namespace std; 13 14 struct Point { 15 int x, y; 16 }p[1100] ; 17 18 int n, h, stack[1100]; 19 20 int Multi(Point p0, Point p1, Point p2){ 21 return (p1.x - p0.x) * (p2.y - p0.y) - (p1.y - p0.y) * (p2.x - p0.x) ; 22 } 23 24 int dis(Point a, Point b){ 25 int x = a.x - b.x , y = a.y - b.y ; 26 return (x * x + y * y) ; 27 } 28 29 bool cmp(Point a, Point b){ 30 int k = Multi(p[0], a, b) ; 31 if(k > 0 || (k == 0 && dis(p[0], a) < dis(p[0], b))) return 1; 32 return 0; 33 } 34 35 void GrahamScan(){ 36 int MIN = 0; 37 for(int i=1; i<n; i++) 38 if(p[MIN].y > p[i].y || (p[MIN].y == p[i].y && p[MIN].x > p[i].x)) 39 MIN = i; 40 Point temp = p[0] ; 41 p[0] = p[MIN], p[MIN] = temp ; 42 sort(p+1, p+n, cmp) ; 43 stack[0] = 0, stack[1] = 1, h = 1; 44 for(int i=2; i<n; i++){ 45 while(Multi(p[stack[h-1]], p[stack[h]], p[i]) <= 0){ 46 h--; 47 if(h == 0) break; 48 } 49 stack[++h] = i; 50 } 51 stack[++h] = 0; 52 } 53 54 bool Judge(){ 55 for(int i=0; i<h; i++){ 56 int num = 0; 57 for(int j=0; j<n; j++) 58 if(Multi(p[stack[i]], p[stack[i+1]], p[j]) == 0) 59 num++; 60 if(num < 3) return 0; 61 } 62 return 1; 63 } 64 65 int main(){ 66 #ifdef ONLINE_JUDGE 67 #else 68 freopen("input.txt","r",stdin); 69 #endif 70 71 int T; 72 scanf("%d", &T) ; 73 while(T--){ 74 scanf("%d", &n) ; 75 for(int i=0; i<n; i++) 76 scanf("%d %d", &p[i].x, &p[i].y) ; 77 if(n < 6){ 78 printf("NO\n") ; 79 continue ; 80 } 81 82 GrahamScan() ; 83 if(h < 3){ 84 printf("NO\n") ; 85 continue ; 86 } 87 bool flag = Judge() ; 88 if(flag) printf("YES\n") ; 89 else printf("NO\n") ; 90 } 91 return 0; 92 93 }