hdu 1348(凸包)

 1 /*

 2 *  凸包

 3 *  注意:给出的点为整点数,不要设某一精度值! 

 4 */

 5 

 6 #include <cmath>

 7 #include <cstdio>

 8 #include <cstdlib>

 9 #include <iostream>

10 

11 using namespace std;

12 

13 const int N = 1005;

14 const double PI = 3.1415927;

15 

16 struct point {

17     double x;

18     double y;

19 }p[N], stack[N];

20 

21 double dis(point A, point B) {

22     return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));

23 }

24 

25 double crossProd(point A, point B, point C) {

26     return (B.x-A.x)*(C.y-A.y) - (B.y-A.y)*(C.x-A.x);

27 }

28 

29 //以最左下的点为基准点,其他各点(逆时针方向)以极角从小到大的排序规则

30 int cmp(const void *a, const void *b) {

31     point *c = (point *)a;

32     point *d = (point *)b;

33     double k = crossProd(p[0], *c, *d);//极角大小转化为求叉乘

34     if (k<0 || !k && dis(p[0], *c)>dis(p[0], *d)) return 1;

35     return -1;

36 }

37 

38 double Graham(int n) {

39     double x = p[0].x;

40     double y = p[0].y;

41     int mi = 0;

42     for (int i=1; i<n; ++i) {//找到最左下的一个点

43         if (p[i].x<x || (p[i].x==x && p[i].y<y)) {

44             x = p[i].x;

45             y = p[i].y;

46             mi = i;

47         }

48     }

49     point tmp = p[mi];

50     p[mi] = p[0];

51     p[0] = tmp;

52     qsort(p+1, n-1, sizeof(point), cmp);

53     p[n] = p[0];

54     stack[0] = p[0];

55     stack[1] = p[1];

56     stack[2] = p[2];

57     int top = 2;

58     for (int i=3; i<=n; ++i) {//加入一个点后,向右偏拐或共线,则上一个点不在凸包内,则--top,该过程直到不向右偏拐或没有三点共线的点 

59         while (crossProd(stack[top-1], stack[top], p[i])<=0 && top>=2) --top;

60         stack[++top] = p[i];//在当前情况下符合凸包的点,入栈

61     }

62     double len = 0;

63     for (int i=0; i<top; ++i) len += dis(stack[i], stack[i+1]);

64     return len;

65 }

66 

67 int main() {

68     int t;

69     while (scanf("%d", &t) != EOF) {

70         while (t--) {

71             int n, l;

72             scanf ("%d%d", &n, &l);

73             for (int i=0; i<n; ++i) scanf ("%lf%lf", &p[i].x, &p[i].y);

74             double ans = Graham(n);

75             ans += PI * (l + l);

76             printf ("%.0lf\n", ans);

77             if (t) printf ("\n");

78         }

79     }

80     return 0;

81 }

 

你可能感兴趣的:(HDU)