HDU 1392 Surround the Trees (Graham求凸包周长)

题目链接

题意 : 让你找出最小的凸包周长 。

思路 : 用Graham求出凸包,然后对每条边求长即可。

Graham详解

 1 #include <stdio.h>

 2 #include <string.h>

 3 #include <iostream>

 4 #include <math.h>

 5 #include <algorithm>

 6 

 7 using namespace std ;

 8 

 9 struct point

10 {

11     int x,y ;

12 }p[110],p1[110];

13 int n ;

14 

15 double dis(point a,point b)

16 {

17     return sqrt(double((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y))) ;

18 }

19 double cross(point a,point b,point c)

20 {

21     return (a.x-c.x)*(b.y-c.y) - (a.y-c.y)*(b.x-c.x) ;

22 }

23 bool cmp(point a,point b)

24 {

25     if(cross(a,b,p[0]) > 0 || cross(a,b,p[0]) == 0 && dis(a,p[0]) < dis(b,p[0]))

26         return true ;

27     return false ;

28 }

29 void Graham()

30 {

31     int cnt;

32     sort(p+1,p+n,cmp) ;

33     p[n] = p[0] ;

34     p1[0] = p[0] ;

35     p1[1] = p[1] ;

36     cnt = 1 ;

37     for(int i = 2 ; i <= n ; i++)

38     {

39         while(cnt >= 1 && cross(p1[cnt-1],p1[cnt],p[i]) <= 0) cnt -- ;

40         p1[ ++cnt] = p[i] ;

41     }

42     double sum = 0.0 ;

43     for(int i = 0 ; i < cnt ; i++)

44         {

45             sum += dis(p1[i],p1[i+1]) ;

46             //printf("*%.2lf*\n",sum) ;

47         }

48         printf("%.2lf\n",sum) ;

49 }

50 int main()

51 {

52     while(~scanf("%d",&n) && n)

53     {

54         int pos = 0 ;

55         for(int i = 0 ; i < n ; i++)

56         {

57             scanf("%d %d",&p[i].x,&p[i].y) ;

58             if(p[pos].y > p[i].y || (p[pos].y == p[i].y && p[i].x < p[pos].x))

59                 pos = i ;

60         }

61         if(n == 1) {puts("0.00");continue ;}

62         if(n == 2)

63         {

64             printf("%.2lf\n",dis(p[1],p[0])) ;

65             continue ;

66         }

67         swap(p[pos],p[0]) ;

68         //printf("%d %d\n",p[0].x,p[0].y) ;

69         Graham() ;

70     }

71     return 0 ;

72 }
View Code

 

你可能感兴趣的:(round)