求出所有点的凸包然后加上半径为L的圆的周长即可
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
#define MAXN 1000
#define pi acos(-1)
struct cnode
{
int x;
int y;
}node[MAXN + 10],p,sta[MAXN + 10];
int n,m;
int dis(const cnode e1,const cnode e2)//距离的平方
{
return (e1.x - e2.x) * (e1.x - e2.x) + (e1.y - e2.y) * (e1.y - e2.y);
}
bool cmp(const cnode e1,const cnode e2)
{
double flag;
flag = (e1.x - p.x) * (e2.y - p.y) - (e1.y - p.y) * (e2.x - p.x);
if(flag > 0)
{
return true;
}
else if(flag < 0)
{
return false;
}
else
{
if(dis(e1,p) >= dis(e2,p))
{
return false;
}
else
{
return true;
}
}
}
bool dir(cnode p0,cnode p1,cnode p2)//叉积
{
double flag;
flag = (p0.x - p1.x) * (p2.y - p1.y) - (p0.y - p1.y) * (p2.x - p1.x);
if(flag >= 0)
{
return true;
}
else
{
return false;
}
}
int Graham_scan()
{
int ymin = 1e9;
int flag = 0;
int xmin = 1e9;
int i;
for(i = 0;i< n;i++)
{
if(node[i].y < ymin)
{
flag = i;
ymin = node[i].y;
}
else if(node[i].y == ymin)
{
if(node[i].x < xmin)
{
xmin = node[i].x;
flag = i;
}
}
}
p = node[flag];
node[flag] = node[0];
node[0] = p;//node[0]最低,最左边的点
sort(&node[1],&node[n],cmp);//按逆时针排
int top = -1;//栈顶
sta[++top] = node[0];
sta[++top] = node[1];
sta[++top] = node[2];
for(i = 3;i < n;i++)
{
while(dir(node[i],sta[top - 1],sta[top]))//看node[i]在不在sta[top-1]sta[top]的顺时针方向
{
top--;//如果在顺时针方向则退栈
}
sta[++top] = node[i];
}
top++;
return top;
}
int main()
{
int i;
while(scanf("%d %d",&n,&m) != EOF)
{
for(i = 0;i < n;i++)
{
scanf("%d %d",&node[i].x,&node[i].y);
}
double ans = 0.0;
int top;
top = Graham_scan();
// cout<<"top"<<" "<<top<<endl;
for(i = 0;i < top;i++)
{
ans += sqrt(dis(sta[i],sta[(i+1) % top]) + 0.0);
}
ans += 2 * m * pi;
printf("%.0f\n",ans);
}
return 0;
}