题意:给出平面上若干个点的坐标,让建一个环形围墙,把所有的点围在里面,且距所有点的距离不小于l。求围墙的最小长度。
分析:凸包周长+半径为l的圆周长
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include
<
iostream
>
#include < cstdio >
#include < cstdlib >
#include < cstring >
#include < cmath >
#include < algorithm >
using namespace 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);
}
bool operator < ( 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 )
return 0 ;
res[ 0 ] = pnt[ 0 ];
if (n == 1 )
return 1 ;
res[ 1 ] = pnt[ 1 ];
if (n == 2 )
return 2 ;
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);
return 0 ;
}
#include < cstdio >
#include < cstdlib >
#include < cstring >
#include < cmath >
#include < algorithm >
using namespace 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);
}
bool operator < ( 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 )
return 0 ;
res[ 0 ] = pnt[ 0 ];
if (n == 1 )
return 1 ;
res[ 1 ] = pnt[ 1 ];
if (n == 2 )
return 2 ;
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);
return 0 ;
}