求围墙的长度 就是里面凸包的周长+半径为L的圆周长
#include "cstring"
#include "iostream"
#include "algorithm"
#include "cstdio"
#include "queue"
#include "set"
#include "cmath"
using namespace std;
typedef long long LL;
const int M=510;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1.00);
const double EPS = 1e-6;
struct point
{
double x,y;
};
struct point a[1005],b[1005],p[2005],p1[2005];
//p:遍历全部点 p1:记录凸包的点
int size; //凸包点个数
bool cmp(point a,point b)
{//按x从小到大排列;x相同的 按y从小到大排列
if(a.x==b.x)
return a.y<b.y;
return a.x<b.x;
}
double chaji(point a,point b,point c)
{
return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
}
double dist(point a,point b)
{
return sqrt((b.x-a.x)*(b.x-a.x)+(b.y-a.y)*(b.y-a.y));
}
void sovle(int n)
{
int i;
double t;
p1[0]=p[0]; //第一个凸包点是第一个点
p1[1]=p[1]; //假设..二............二....
size=1; //记录当前假设的凸包点
for(i=2;i<n;i++)//遍历所有点
{
t=chaji(p1[size-1],p1[size],p[i]);//算两个凸包点与该点 向量的叉积
while(t<=0)//叉积<=0 该点不是凸包点
{
size--;
if(t==0 || size==0)//垂直 或者凸包点全部遍历完
break;
t=chaji(p1[size-1],p1[size],p[i]);//直到该点遍历完全部凸包点或者 满足>0为凸包点
}
p1[++size]=p[i];//记录下一个凸包点
}
p1[++size]=p[n-2];
for(i=n-3;i>=0;i--)//往回找 直到第一个凸包点
{
t=chaji(p1[size-1],p1[size],p[i]);
while(t<=0)
{
size--;
if(t==0 || size==0)
break;
t=chaji(p1[size-1],p1[size],p[i]);
}
p1[++size]=p[i];
}
}
int main()
{
int n,i;
int l;
double sum;
while(~scanf("%d%d",&n,&l))
{
for(i=0;i<n;i++)
scanf("%lf%lf",&p[i].x,&p[i].y);
sort(p,p+n,cmp);
sovle(n);
sum=0;
for(i=0;i<size;i++)//计算周长
sum=sum+dist(p1[i],p1[i+1]);
if(size==2)//若只有2个凸包点
sum=sum/2;
double s=PI*l*2;
//printf("%.2lf\n",sum+s+0.5);
printf("%d\n",int(sum+s+0.5));
}
return 0;
}