POJ 1113 Wall(Graham求凸包周长)

题目链接

题意 : 求凸包周长+一个完整的圆周长。

因为走一圈,经过拐点时,所形成的扇形的内角和是360度,故一个完整的圆。

POJ 1113 Wall(Graham求凸包周长)

思路 : 求出凸包来,然后加上圆的周长

 1 #include <stdio.h>

 2 #include <string.h>

 3 #include <iostream>

 4 #include <cmath>

 5 #include <algorithm>

 6 

 7 const double PI = acos(-1.0) ;

 8 using namespace std ;

 9 

10 struct point

11 {

12     double x,y ;

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

14 int n ,m;

15 

16 double dis(point a,point b)

17 {

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

19 }

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

21 {

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

23 }

24 bool cmp(point a,point b)

25 {

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

27         return true ;

28     return false ;

29 }

30 void Graham()

31 {

32     int cnt;

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

34     p[n] = p[0] ;

35     p1[0] = p[0] ;

36     p1[1] = p[1] ;

37     cnt = 1 ;

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

39     {

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

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

42     }

43     double sum = 0.0 ;

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

45         {

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

47         }

48         printf("%.0lf\n",sum+2*PI*m) ;

49 }

50 int main()

51 {

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

53     {

54         int pos = 0 ;

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

56         {

57             scanf("%lf %lf",&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

 

你可能感兴趣的:(poj)