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 } 

 

 

你可能感兴趣的:(uva)