POJ1113-Wall-求凸包周长
题意:
国王要把n个城堡外建城墙,使得城墙距离任一城堡的距离都大于L,给出n个城堡的坐标,求城墙的最小周长。
思路:
利用城堡的坐标可以形成一个凸包,在拐角处画一个半径为L的圆弧,最终所有圆弧合起来正好是一个半径为L的圆,所以答案就是凸包的周长+半径为L的圆的周长。
先求凸包的顶点,再叉积求面积,两点间的距离公式求周长。
注意:
因为结果四舍五入,
处理方法:
输出用%.0f,表示输出浮点数整数部分,省略小数部分;
或者在double后面加上0.5,在最后输出的时候把double类型强制转换成int即可,注意加(int),不要直接%d输出。
AC代码:
1 #include<iostream> 2 #include<stdio.h> 3 #include<algorithm> 4 #include<cmath> 5 #include<string.h> 6 7 using namespace std; 8 typedef long long ll; 9 #define inf 0x3f3f3f3f 10 #define PI acos(-1) 11 const int N=1020; 12 13 struct node 14 { 15 double x,y; 16 }p[N],st[N]; 17 int n; 18 19 double cross(node a,node b,node c)//计算叉积 ab*ac 20 { 21 return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y); 22 } 23 24 int cmp(node a,node b) 25 { 26 if(a.x!=b.x) 27 return a.x<b.x; 28 return a.y<b.y; 29 } 30 31 double dist(node a,node b) 32 { 33 return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); 34 } 35 36 int Andrew() 37 { 38 sort(p,p+n,cmp); 39 int x=0; 40 for(int i=0;i<n;i++) 41 { 42 while(x>1&&cross(st[x-2],st[x-1],p[i])<=0) 43 x--; 44 st[x++]=p[i]; 45 } 46 int k=x; 47 for(int i=n-2;i>=0;i--) 48 { 49 while(x>k&&cross(st[x-2],st[x-1],p[i])<=0) 50 x--; 51 st[x++]=p[i]; 52 } 53 return x-1; 54 } 55 56 int main() 57 { 58 int L; 59 while(~scanf("%d %d",&n,&L)) 60 { 61 memset(st,0,sizeof(st)); 62 for(int i=0;i<n;i++) 63 scanf("%lf %lf",&p[i].x,&p[i].y); 64 int x=Andrew(); 65 double ans=0; 66 for(int i=0;i<x;i++) 67 ans+=dist(st[i],st[i+1]); 68 ans=ans+dist(st[0],st[x])+2*PI*L+0.5;//+0.5 69 printf("%d\n",(int)ans);//lf 70 } 71 return 0; 72 }