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 } 

 

 

 

posted @ 2013-02-24 18:54  proverbs  阅读(237)  评论(0编辑  收藏  举报