Wall
题意:将宫殿围起来,要求城墙离宫殿距离不小于L且花费最小。
Andrew求凸包,转角处合起来刚好是个半径为L的圆。
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #include <cmath> 6 using namespace std; 7 const int maxn=1010; 8 const double pi=acos(-1.0); 9 struct Node{ 10 int x,y; 11 bool operator <(const Node& a)const { 12 return x<a.x||x==a.x&&y<a.y; 13 } 14 Node operator - (const Node& a){ 15 return Node{x-a.x,y-a.y}; 16 } 17 }node[maxn],p[maxn]; 18 int cross(Node a,Node b){ 19 return a.x*b.y-a.y*b.x; 20 } 21 double dis(Node a,Node b){ 22 double dx=a.x-b.x; 23 double dy=a.y-b.y; 24 return sqrt(dx*dx+dy*dy); 25 } 26 int main(){ 27 int n,r; 28 while(scanf("%d%d",&n,&r)!=EOF){ 29 for(int i=0;i<n;i++) scanf("%d%d",&node[i].x,&node[i].y); 30 sort(node,node+n); 31 int m=0; 32 for(int i=0;i<n;i++){ 33 while(m>1&&cross(p[m-1]-p[m-2],node[i]-p[m-2])<=0) m--; 34 p[m++]=node[i]; 35 } 36 int k=m; 37 for(int i=n-2;i>=0;i--){ 38 while(m>k&&cross(p[m-1]-p[m-2],node[i]-p[m-2])<=0) m--; 39 p[m++]=node[i]; 40 } 41 if(m>1) m--; 42 double ans=0; 43 for(int i=0;i<m;i++) ans+=dis(p[i],p[i+1]); 44 ans+=dis(p[0],p[m]); 45 ans+=2*pi*r; 46 printf("%d\n",(int)(ans+0.5)); 47 } 48 return 0; 49 }