poj1113

题意:给出平面上若干个点的坐标,让建一个环形围墙,把所有的点围在里面,且距所有点的距离不小于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;
}
原文地址:https://www.cnblogs.com/rainydays/p/2089193.html