UVA 11626 凸包(含共线)

题意:

给出凸包上的点(无序的),要求从左下角开始按顺序逆时针输出所有凸包上的点~

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 } 
原文地址:https://www.cnblogs.com/proverbs/p/2927818.html