题意:
给 n 个点,要求一个环形把所有的点都包围起来,并且使得环形距所有点的距离至少为
L ,求最小的环形的周长?
思路:
凸包求解,其实看完题目给的图片,就知道答案就是 = 凸包周长 + 2⋅π⋅L
凸包求解学习资料,建议先看一下 这个,然后读代码的时候就很简单了!作为入门题还是不错的。
代码:
#include <cmath>
#include <cstdio>
#include <algorithm>
#define S first
#define E second
#define eps 1e-8
using namespace std;
const int N = 1e3 + 10;
const double PI = acos(-1.0);
typedef double TP;
struct Point
{
TP x, y;
Point(TP x = 0, TP y = 0) :x(x), y(y){}
void input()
{
scanf("%lf %lf", &x, &y);
}
Point operator - (const Point& p)
{
return Point(x - p.x, y - p.y);
}
TP operator ^ (const Point& p)
{
return (x * p.y - y * p.x);
}
};
int dcmp(double x)
{
if(fabs(x) < eps) return 0;
else return x < 0 ? -1 : 1;
}
TP cross(Point& S, Point& E, Point& O)
{
return (S - O) ^ (E - O);
}
double dis(Point& a, Point& b)
{
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
bool pointCmp(const Point& a, const Point& b)
{
if(dcmp(a.x - b.x) == 0) return a.y < b.y;
return a.x < b.x;
}
void convexHull(Point *p, int n, Point *C, int& m)
{
sort(p, p + n, pointCmp);
m = 0;
for(int i = 0;i < n;i ++) {
while(m > 1 && cross(C[m-1], p[i], C[m-2]) <= 0) m --;
C[m ++] = p[i];
}
int k = m;
for(int i = n - 2;i >= 0;i --) {
while(m > k && cross(C[m-1], p[i], C[m-2]) <= 0) m --;
C[m ++] = p[i];
}
if(m > 1) m --;
}
int n, m;
Point p[N], C[N];
int main()
{
int l;
scanf("%d%d", &n, &l);
for(int i = 0;i < n;i ++) p[i].input();
convexHull(p, n, C, m);
double ans = 2 * PI * l;
for(int i = 0;i < m;i ++) {
ans += dis(C[i], C[(i + 1) % m]);
}
printf("%d\n", int(ans + 0.5));
return 0;
}