POJ 1228 稳定凸包
题意:
这里讲的很清楚:
http://www.cnblogs.com/xdruid/archive/2012/06/20/2555536.html
我们一般的凸包模板都是最简的,而稍作变化就能做到“最繁”的~
View Code
1 #include <iostream> 2 #include <cstring> 3 #include <cstdlib> 4 #include <algorithm> 5 #include <cstdio> 6 #include <cmath> 7 8 #define N 2222 9 10 using namespace std; 11 12 struct PO 13 { 14 int x,y; 15 }p[N]; 16 17 int n,top,stk[N],fg[N]; 18 19 inline bool cmp(const PO &a,const PO &b) 20 { 21 if(a.x==b.x) return a.y<b.y; 22 return a.x<b.x; 23 } 24 25 inline void read() 26 { 27 memset(fg,0,sizeof fg); 28 scanf("%d",&n); 29 for(int i=1;i<=n;i++) scanf("%d%d",&p[i].x,&p[i].y); 30 } 31 32 inline int cross(PO &a,PO &b,PO &c) 33 { 34 return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x); 35 } 36 37 inline int dot(PO &a,PO &b,PO &c) 38 { 39 return (b.x-a.x)*(c.x-a.x)+(b.y-a.y)*(c.y-a.y); 40 } 41 42 inline void graham()//带共线的graham 43 { 44 sort(p+1,p+1+n,cmp); 45 top=0; 46 stk[++top]=1; stk[++top]=2; 47 int tmp; 48 for(int i=3;i<=n;i++) 49 { 50 while(top>=2&&((tmp=cross(p[stk[top-1]],p[stk[top]],p[i]))<0||(tmp==0&&dot(p[stk[top-1]],p[stk[top]],p[i])<=0))) top--; 51 stk[++top]=i; 52 53 } 54 int tp=top; 55 for(int i=n-1;i>=1;i--) 56 { 57 while(top>=tp+1&&((tmp=cross(p[stk[top-1]],p[stk[top]],p[i]))<0||(tmp==0&&dot(p[stk[top-1]],p[stk[top]],p[i])<=0))) top--; 58 stk[++top]=i; 59 } 60 } 61 62 inline bool allinline()//全部共线 63 { 64 for(int i=3;i<=n;i++) 65 if(cross(p[1],p[2],p[i])!=0) return false; 66 return true; 67 } 68 69 inline bool judge() 70 { 71 if(n<6) return false; 72 if(allinline()) return false; 73 return true; 74 } 75 76 inline void go() 77 { 78 if(!judge()) {puts("NO");return;} 79 graham(); 80 if(top-1<6) {puts("NO");return;} 81 stk[top+1]=stk[2]; 82 for(int i=1;i<top;i++) 83 if(cross(p[stk[i]],p[stk[i+1]],p[stk[i+2]])==0) fg[i+1]=fg[i+2]=1; 84 fg[1]|=fg[top]; fg[2]|=fg[top+1]; 85 for(int i=1;i<top;i++) 86 if(!fg[i]) {puts("NO");return;} 87 puts("YES"); 88 } 89 90 int main() 91 { 92 int cas; scanf("%d",&cas); 93 while(cas--) read(),go(); 94 return 0; 95 }
没有人能阻止我前进的步伐,除了我自己!