围墙的周长= 凸包 周长+圆的周长。
代码如下:
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 }