题解:本题用到的依然是凸包来求,最短的周长,只是多加了一个圆的长度而已,套用模板,就能搞定;
AC代码:
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cmath> 5 using namespace std; 6 int m,n; 7 struct p 8 { 9 double x,y; 10 friend int operator <(p a, p b) 11 { 12 if(a.x<b.x || ( a.x==b.x && a.y<b.y)) 13 return 1; 14 return 0; 15 } 16 }a[1010],ans[1010]; 17 double judge(p a, p b ,p c) 18 { 19 return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y); 20 } 21 int getnumber()//寻找关键点,来求出最短的周长 22 { 23 int k=0; 24 for(int i=0; i<m; i++) 25 { 26 while(k>1 && judge(ans[k-2],ans[k-1],a[i])<=0) 27 { 28 k--; 29 } 30 ans[k++]=a[i]; 31 } 32 int k1=k; 33 for(int i=m-1; i>=0; i--) 34 { 35 while(k>k1 && judge(ans[k-2],ans[k-1],a[i])<=0) 36 { 37 k--; 38 } 39 ans[k++]=a[i]; 40 } 41 return k-1;//第一个点存了两次; 42 } 43 44 int main() 45 { 46 scanf("%d %d",&m,&n); 47 for(int i=0; i<m; i++) 48 scanf("%lf %lf",&a[i].x,&a[i].y); 49 sort(a,a+m); 50 int top=getnumber(); 51 double ans1=0; 52 int i; 53 for( i=0; i<top; i++){ 54 ans1+=sqrt((ans[i].x-ans[i+1].x)*(ans[i].x-ans[i+1].x)+(ans[i].y-ans[i+1].y)*(ans[i].y-ans[i+1].y)); 55 } 56 //其实最后只需要加上一个圆的周长就ok了,多边形的外角和为360度; 57 ans1+=2*3.141592653*n; 58 printf("%.0f ",ans1);//G++ 这个才能过不能用(.0l%),C++可以 59 return 0; 60 }