zrq495
www.zrq495.com

围墙的周长= 凸包 周长+圆的周长。

代码如下:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<algorithm>
 7 
 8 #define PI 3.141592653
 9 
10 using namespace std;
11 
12 typedef struct node
13 {
14     int x, y;
15 }node;
16 
17 node f[1002];
18 
19 bool cmp(node a, node b)    //叉积排序 如果相等 近的优先
20 {
21     if ((a.x-f[0].x)*(b.y-f[0].y) == (b.x-f[0].x)*(a.y-f[0].y))
22         return ((a.x-f[0].x)*(a.x-f[0].x)+(a.y-f[0].y)*(a.y-f[0].y))
23                 < ((b.x-f[0].x)*(b.x-f[0].x)+(b.y-f[0].y)*(b.y-f[0].y));
24     return ((a.x-f[0].x)*(b.y-f[0].y) > (b.x-f[0].x)*(a.y-f[0].y));
25 }
26 
27 bool left(int i, int j, int k)  //判断是否左转
28 {
29     int x1=f[j].x-f[i].x;
30     int y1=f[j].y-f[i].y;
31     int x2=f[k].x-f[j].x;
32     int y2=f[k].y-f[j].y;
33     if (x1*y2>x2*y1)    //这种情况为不要直线上多余的点 如果想要应用 >=
34         return true;
35     return false;
36 }
37 
38 double dis(int i, int j)    //求两点距离
39 {
40     return sqrt((f[i].x-f[j].x)*(f[i].x-f[j].x)+(f[i].y-f[j].y)*(f[i].y-f[j].y));
41 }
42 
43 int main()
44 {
45     int st[1002];
46     int n, l, i, j, k;
47     while(scanf("%d%d", &n, &l)!=EOF)
48     {
49         k=0;
50         for (i=0; i<n; i++)
51         {
52             scanf("%d%d", &f[i].x, &f[i].y);
53             if (f[i].y < f[k].y || (f[i].y == f[k].y && f[i].x < f[k].x))
54                 k=i;
55         }
56         if (k != 0)
57         {
58             swap(f[0].x, f[k].x);
59             swap(f[0].y, f[k].y);
60         }
61         sort(f+1, f+n, cmp);
62         int top=0;
63         st[top++]=0;
64         st[top++]=1;
65         st[top++]=2;
66         for (i=3; i<n; )
67         {
68             if (top < 2 || left(st[top-2], st[top-1], i))    //是左转则入栈加一 (I<2)的情况是对于开始就有直线又不要直线上多余点的情况,
69                 st[top++]=i++;                    //防止越界。如果直线上多余的点也要则可不写,但会有多余的点使得效率低
70             else
71                 top--;        //否则出栈
72         }
73         st[top]=st[0];
74         double sum=2*PI*l;    //初始为圆的周长
75         for (i=0; i<top; i++)  
76         {
77             sum+=dis(st[i], st[i+1]);
78         }
79         printf("%d\n", (int )(sum+0.49999));    //四舍五入
80     }
81     return 0;
82 }
posted on 2012-08-16 19:04  zrq495  阅读(186)  评论(0编辑  收藏  举报