给出 n 个点,以及数 L,要求修一面城墙花费最少的资源,使得每个点到达城墙的距离全都大于 L
求出这 n 各点所形成的凸包的周长+以 L 为半径的圆的周长即可
const int N=1e4+5;
int i,j,k;
int n,m,t;
struct Point
{
double x,y;
Point(double x=0,double y=0):x(x),y(y){}
}p[N],ch[N];
typedef Point Vector;
Vector operator+(Vector a,Vector b){ return Vector(a.x-b.x,a.y-b.y); }
Vector operator-(Vector a,Vector b){ return Vector(a.x-b.x,a.y-b.y); }
double Cross(Vector a,Vector b){ return a.x*b.y-a.y*b.x; }
double Dot(Vector a,Vector b){ return a.x*b.x+a.y*b.y; }
double length(Vector a){ return sqrt(Dot(a,a)); }
bool cmp(Point a,Point b)
{
return a.x==b.x?a.y<b.y:a.x<b.x;
}
int ConvexHull(Point *p,int n,Point *ch)
{
sort(p,p+n,cmp);
int m=0;
for(int i=0;i<n;i++){
while(m>1 && Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0 ) m--;
ch[m++]=p[i];
}
int k=m;
for(int i=n-2;i>=0;i--){
while(m>k && Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0 ) m--;
ch[m++]=p[i];
}
if(n>1) m--;
return m;
}
int main()
{
//IOS;
int L;
while(~sdd(n,L)){
for(int i=0;i<n;i++) sff(p[i].x,p[i].y);
int m=ConvexHull(p,n,ch);
double ans=0;
for(int i=0;i<=m;i++){
ans+=length(ch[i]-ch[(i+1)%(m+1)]);
}
pd((int)(ans+pi*L*2+0.5));
}
//PAUSE;
return 0;
}