题目:http://poj.org/problem?id=1113
题意:给定多边形城堡的n个顶点,绕城堡外面建一个围墙,围住所有点,并且墙与所有点的距离至少为L,求这个墙最小的长度。
公式:
城堡围墙长度最小值 = 城堡顶点坐标构成的散点集的凸包总边长 + 半径为L的圆周长
View Code
1 #include <iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #define PI 3.1415926535 6 using namespace std; 7 const double eps=1e-6; 8 typedef struct node 9 { 10 int x,y; 11 }point; 12 int n; 13 point pt[1100]; 14 point res[1100]; 15 bool cmp(point a,point b) 16 { 17 if(a.x==b.x) 18 return a.y<b.y; 19 else 20 return a.x<b.x; 21 } 22 int dcml(double x) 23 { 24 if(fabs(x)<eps) 25 return 0; 26 if(x<0) 27 return -1; 28 else 29 return 1; 30 } 31 double dot(int x1,int y1,int x2,int y2) 32 { 33 return x1*y2-x2*y1; 34 } 35 int cross(point a,point b,point c) 36 { 37 return dcml(dot(a.x-c.x,a.y-c.y,b.x-c.x,b.y-c.y)); 38 } 39 int dist(point a,point b) 40 { 41 return ((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); 42 } 43 int main() 44 { 45 int L; 46 scanf("%d%d",&n,&L); 47 int i; 48 for(i=0;i<n;i++) 49 { 50 scanf("%d%d",&pt[i].x,&pt[i].y); 51 } 52 sort(pt,pt+n,cmp); 53 int m; 54 m=0; 55 for(i=0;i<n;i++) 56 { 57 while(m>1&&cross(res[m-1],pt[i],res[m-2])<=0) 58 m--; 59 res[m++]=pt[i]; 60 } 61 int k=m; 62 for(i=n-2;i>=0;i--) 63 { 64 while(m>k&&cross(res[m-1],pt[i],res[m-2])<=0) 65 m--; 66 res[m++]=pt[i]; 67 } 68 if(n>1) 69 m--; 70 double dis=0; 71 for(i=0;i<m-1;i++) 72 { 73 dis+=sqrt(dist(res[i],res[i+1])); 74 } 75 dis+=sqrt(dist(res[0],res[m-1])); 76 dis+=2*PI*L; 77 printf("%d",(int)(dis+0.5)); 78 return 0; 79 }