/* 题意: 求得n个点的凸包。然后求与凸包相距l的外圈的周长。 答案为n点的凸包周长加上半径为L的圆的周长 */ # include <stdio.h> # include <math.h> # include <string.h> # include <algorithm> using namespace std; # define PI acos(-1.0) struct node { int x; int y; }; node a[1010],res[1010]; bool cmp(node a1,node a2) { if(a1.x==a2.x) return a1.y<a2.y; return a1.x<a2.x; } int cross(node a1,node a2,node a3) { return (a1.x-a3.x)*(a2.y-a3.y)-(a2.x-a3.x)*(a1.y-a3.y); } int convex(int n)//求凸包上的点 { int m=0,i,j,k; sort(a,a+n,cmp); //求得下凸包。逆时针 //已知凸包点m个。假设新增加点为i。则向量(m-2,i)必然要在(m-2,m-1)的逆时针方向才符合凸包的性质 //若不成立。则m-1点不在凸包上。 for(i=0;i<n;i++) { while(m>1&&cross(res[m-1],a[i],res[m-2])<=0) m--; res[m++]=a[i]; } k=m; //求得上凸包 for(i=n-2;i>=0;i--) { while(m>k&&cross(res[m-1],a[i],res[m-2])<=0) m--; res[m++]=a[i]; } if(n>1) m--; return m; } double length(node a1,node a2) { return sqrt(1.0*(a1.x-a2.x)*(a1.x-a2.x)+(a1.y-a2.y)*(a1.y-a2.y)); } int main() { int t,n,i,L,m; while(~scanf("%d",&t)) { while(t--) { scanf("%d%d",&n,&L); for(i=0;i<n;i++) scanf("%d%d",&a[i].x,&a[i].y); m=convex(n); double ans=0; for(i=1;i<m;i++) ans+=length(res[i],res[i-1]); ans+=length(res[0],res[m-1]); ans+=2*PI*L; printf("%.0lf ",ans); if(t) printf(" "); } } return 0; }