由图可知 路径长度就是图包+一个以L为半径的圆
四舍五入很玄学。。。
/* 取一个最第点 极角排序 类似单调队列地删点 */ #include<cmath> #include<cstdio> #include<algorithm> using namespace std; const int N=1e4+50; const double eps=1e-7; const double Pi=acos(-1); struct Point { double x,y; Point(){} Point(double _x,double _y){x=_x,y=_y;}; }p[N],q[N]; Point operator - (Point A,Point B) {return Point(A.x-B.x,A.y-B.y);} double operator * (Point A,Point B) {return A.x*B.x+A.y*B.y;} double operator ^ (Point A,Point B) {return A.x*B.y-A.y*B.x;} double dist(Point A,Point B) {return sqrt((A-B)*(A-B));} bool cmp(Point a,Point b) { double c=(a-p[1])^(b-p[1]); if(fabs(c)<=eps) return dist(a,p[1])<dist(b,p[1]); return c<eps; } int main() { int n,r; scanf("%d%d",&n,&r); for(int i=1;i<=n;i++) { scanf("%lf%lf",&p[i].x,&p[i].y); if(i>1&&p[i].y<p[1].y) swap(p[i],p[1]); } sort(p+2,p+n+1,cmp); q[1]=p[1]; int ed=1; for(int i=2;i<=n;i++) { while(ed>1&&((p[i]-q[ed-1])^(q[ed]-q[ed-1]))<=eps) ed--; q[++ed]=p[i]; } q[ed+1]=p[1]; double res=0; for(int i=1;i<=ed;i++) res+=dist(q[i],q[i+1]); printf("%d\n",(int)(res+Pi*2*r+0.5)); // 玄学的四舍五入 return 0; }