题意:给出平面上若干个点的坐标,让建一个环形围墙,把所有的点围在里面,且距所有点的距离不小于l。求围墙的最小长度。
分析:凸包周长+半径为l的圆周长
View Code
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
usingnamespace std;
#define maxn 1005
struct point
{
double x, y;
} pnt[maxn], res[maxn];
int n, l;
bool mult(point sp, point ep, point op)
{
return (sp.x - op.x) * (ep.y - op.y) >= (ep.x - op.x) * (sp.y - op.y);
}
booloperator<(const point &l, const point &r)
{
return l.y < r.y || (l.y == r.y && l.x < r.x);
}
int graham(point pnt[], int n, point res[])
{
int i, len, top =1;
sort(pnt, pnt + n);
if (n ==0)
return0;
res[0] = pnt[0];
if (n ==1)
return1;
res[1] = pnt[1];
if (n ==2)
return2;
res[2] = pnt[2];
for (i =2; i < n; i++)
{
while (top && mult(pnt[i], res[top], res[top -1]))
top--;
res[++top] = pnt[i];
}
len = top;
res[++top] = pnt[n -2];
for (i = n -3; i >=0; i--)
{
while (top != len && mult(pnt[i], res[top], res[top -1]))
top--;
res[++top] = pnt[i];
}
return top;
}
double dis(point &p, point &q)
{
double x1 = p.x - q.x, y1 = p.y - q.y;
return sqrt(x1 * x1 + y1 * y1);
}
int main()
{
//freopen("t.txt", "r", stdin);
scanf("%d%d", &n, &l);
for (int i =0; i < n; i++)
scanf("%lf%lf", &pnt[i].x, &pnt[i].y);
int tot = graham(pnt, n, res);
double ans = l *2*3.14159265;
for (int i =0; i < tot; i++)
ans += dis(res[i], res[(i +1) % tot]);
printf("%.0f\n", ans);
return0;
}
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
usingnamespace std;
#define maxn 1005
struct point
{
double x, y;
} pnt[maxn], res[maxn];
int n, l;
bool mult(point sp, point ep, point op)
{
return (sp.x - op.x) * (ep.y - op.y) >= (ep.x - op.x) * (sp.y - op.y);
}
booloperator<(const point &l, const point &r)
{
return l.y < r.y || (l.y == r.y && l.x < r.x);
}
int graham(point pnt[], int n, point res[])
{
int i, len, top =1;
sort(pnt, pnt + n);
if (n ==0)
return0;
res[0] = pnt[0];
if (n ==1)
return1;
res[1] = pnt[1];
if (n ==2)
return2;
res[2] = pnt[2];
for (i =2; i < n; i++)
{
while (top && mult(pnt[i], res[top], res[top -1]))
top--;
res[++top] = pnt[i];
}
len = top;
res[++top] = pnt[n -2];
for (i = n -3; i >=0; i--)
{
while (top != len && mult(pnt[i], res[top], res[top -1]))
top--;
res[++top] = pnt[i];
}
return top;
}
double dis(point &p, point &q)
{
double x1 = p.x - q.x, y1 = p.y - q.y;
return sqrt(x1 * x1 + y1 * y1);
}
int main()
{
//freopen("t.txt", "r", stdin);
scanf("%d%d", &n, &l);
for (int i =0; i < n; i++)
scanf("%lf%lf", &pnt[i].x, &pnt[i].y);
int tot = graham(pnt, n, res);
double ans = l *2*3.14159265;
for (int i =0; i < tot; i++)
ans += dis(res[i], res[(i +1) % tot]);
printf("%.0f\n", ans);
return0;
}