题意:
给出凸包上的点(无序的),要求从左下角开始按顺序逆时针输出所有凸包上的点~
PS:凸包上的连续三个点存在共线。
题解:
直接套用可以处理共线的凸包模板~
做这个题主要是为了验证模板对不对~
View Code
1 #include <iostream> 2 #include <cstring> 3 #include <cstdlib> 4 #include <algorithm> 5 #include <cstdio> 6 #include <cmath> 7 8 #define N 222222 9 10 using namespace std; 11 12 struct PO 13 { 14 long long x,y; 15 }p[N]; 16 17 int n,top,stk[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 char str[3]; int sn; n=0; 28 scanf("%d",&sn); 29 for(int i=1,a,b;i<=sn;i++) 30 { 31 scanf("%d%d%s",&a,&b,str); 32 if(str[0]=='N') continue; 33 p[++n].x=(long long)a; p[n].y=(long long)b; 34 } 35 } 36 37 inline long long cross(PO &a,PO &b,PO &c) 38 { 39 return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x); 40 } 41 42 inline long long dot(PO &a,PO &b,PO &c) 43 { 44 return (b.x-a.x)*(c.x-a.x)+(b.y-a.y)*(c.y-a.y); 45 } 46 47 inline void graham()//带共线的graham 48 { 49 sort(p+1,p+1+n,cmp); 50 top=0; 51 stk[++top]=1; stk[++top]=2; 52 long long tmp; 53 for(int i=3;i<=n;i++) 54 { 55 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--; 56 stk[++top]=i; 57 58 } 59 int tp=top; 60 for(int i=n-1;i>=1;i--) 61 { 62 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--; 63 stk[++top]=i; 64 } 65 } 66 67 inline void go() 68 { 69 graham(); 70 printf("%d\n",n); 71 for(int i=1;i<top;i++) printf("%lld %lld\n",p[stk[i]].x,p[stk[i]].y); 72 } 73 74 int main() 75 { 76 int cas; scanf("%d",&cas); 77 while(cas--) read(),go(); 78 return 0; 79 }