题意:
一个城墙 有n 个点描述, 国王想建一个周长最短的墙,使墙的任意一点到城墙的距离都 > L。求这面墙的周长。
题解":
最短周长 = 凸包周长 + 半径为 l 的圆的周长。
还要注意的是这道题 不能 将共线点去掉
1 #include<cstdio>
2 #include<cstring>
3 #include<cmath>
4 #include<iostream>
5 #include<algorithm>
6 #include<set>
7 #include<map>
8 #include<queue>
9 #include<vector>
10 #include<string>
11 #define Min(a,b) a<b?a:b
12 #define Max(a,b) a>b?a:b
13 #define CL(a,num) memset(a,num,sizeof(a));
14 #define maxn 1010
15 #define eps 1e-12
16 #define inf 100000000
17 #define mx 1<<60
18 #define ll __int64
19 const double pi = acos(-1.0);
20 using namespace std;
21 struct point
22 {
23 double x,y;
24 }p[maxn];
25 int stack[maxn];
26 int dblcmp(double x)
27 {
28 if(fabs(x) < eps) return 0;
29 if(x < 0) return -1;
30 else return 1;
31 }
32 double det(double x1,double y1,double x2,double y2)
33 {
34 return x1*y2 - x2*y1 ;
35 }
36 double cross(point a, point b, point c)
37 {
38 return det(b.x - a.x, b.y - a.y, c.x - a.x, c.y - a.y);
39 }
40 int cmp(point a,point b)
41 {
42 if(a.y != b.y) return a.y < b.y;
43 else return a.x < b.x;
44 }
45 int top ,n;
46 void graham()
47 {
48
49 int i,len;
50 top = 0;
51 sort(p,p+n,cmp);
52
53 if(n == 0) return ;stack[top++] = 0;
54 if(n == 1) return ;stack[top++] = 1;
55
56 for(i = 2 ;i<n;i++)//求右链
57 {
58 while(top&&dblcmp(cross(p[stack[top - 1]],p[stack[top - 2]],p[i])) > 0) top--;
59
60 stack[top++] = i;
61 }
62
63 //dblcmp(cross(p[stack[top - 1]],p[stack[top - 2]],p[i])) 可以直接是 cross
64 len = top ;
65
66 for(i = n - 2;i >= 0;i--)//求左链
67 {
68 while(top != len && dblcmp(cross(p[stack[top - 1]],p[stack[top - 2]],p[i])) > 0)top--;
69 stack[top++] = i;
70
71 }
72 top--;//第一个点入栈两次 所以 减 1
73
74 }
75 double dis(point a,point b)
76 {
77 double x1 = a.x;
78 double y1 = a.y;
79 double x2 = b.x;
80 double y2 = b.y;
81 return sqrt((x1 - x2)*(x1 - x2)+ (y1 - y2)*(y1 - y2));
82 }
83 int main()
84 {
85
86
87 int i,s,j;
88 //freopen("data.txt","r",stdin);
89 int l;
90 while(scanf("%d%d",&n,&l)!=EOF)
91 {
92 for(i = 0;i < n;i++)
93 {
94 scanf("%lf%lf",&p[i].x,&p[i].y);
95 }
96 graham();
97 double ans = 0 ;
98
99 for(i = 0 ;i < top;i++)
100 {
101 ans += dis(p[stack[i]],p[stack[i + 1]]);
102 }
103
104 ans+=2*pi*l;
105 printf("%.lf\n",ans);
106 }
107
108 }
2 #include<cstring>
3 #include<cmath>
4 #include<iostream>
5 #include<algorithm>
6 #include<set>
7 #include<map>
8 #include<queue>
9 #include<vector>
10 #include<string>
11 #define Min(a,b) a<b?a:b
12 #define Max(a,b) a>b?a:b
13 #define CL(a,num) memset(a,num,sizeof(a));
14 #define maxn 1010
15 #define eps 1e-12
16 #define inf 100000000
17 #define mx 1<<60
18 #define ll __int64
19 const double pi = acos(-1.0);
20 using namespace std;
21 struct point
22 {
23 double x,y;
24 }p[maxn];
25 int stack[maxn];
26 int dblcmp(double x)
27 {
28 if(fabs(x) < eps) return 0;
29 if(x < 0) return -1;
30 else return 1;
31 }
32 double det(double x1,double y1,double x2,double y2)
33 {
34 return x1*y2 - x2*y1 ;
35 }
36 double cross(point a, point b, point c)
37 {
38 return det(b.x - a.x, b.y - a.y, c.x - a.x, c.y - a.y);
39 }
40 int cmp(point a,point b)
41 {
42 if(a.y != b.y) return a.y < b.y;
43 else return a.x < b.x;
44 }
45 int top ,n;
46 void graham()
47 {
48
49 int i,len;
50 top = 0;
51 sort(p,p+n,cmp);
52
53 if(n == 0) return ;stack[top++] = 0;
54 if(n == 1) return ;stack[top++] = 1;
55
56 for(i = 2 ;i<n;i++)//求右链
57 {
58 while(top&&dblcmp(cross(p[stack[top - 1]],p[stack[top - 2]],p[i])) > 0) top--;
59
60 stack[top++] = i;
61 }
62
63 //dblcmp(cross(p[stack[top - 1]],p[stack[top - 2]],p[i])) 可以直接是 cross
64 len = top ;
65
66 for(i = n - 2;i >= 0;i--)//求左链
67 {
68 while(top != len && dblcmp(cross(p[stack[top - 1]],p[stack[top - 2]],p[i])) > 0)top--;
69 stack[top++] = i;
70
71 }
72 top--;//第一个点入栈两次 所以 减 1
73
74 }
75 double dis(point a,point b)
76 {
77 double x1 = a.x;
78 double y1 = a.y;
79 double x2 = b.x;
80 double y2 = b.y;
81 return sqrt((x1 - x2)*(x1 - x2)+ (y1 - y2)*(y1 - y2));
82 }
83 int main()
84 {
85
86
87 int i,s,j;
88 //freopen("data.txt","r",stdin);
89 int l;
90 while(scanf("%d%d",&n,&l)!=EOF)
91 {
92 for(i = 0;i < n;i++)
93 {
94 scanf("%lf%lf",&p[i].x,&p[i].y);
95 }
96 graham();
97 double ans = 0 ;
98
99 for(i = 0 ;i < top;i++)
100 {
101 ans += dis(p[stack[i]],p[stack[i + 1]]);
102 }
103
104 ans+=2*pi*l;
105 printf("%.lf\n",ans);
106 }
107
108 }