题意:给定多边形城堡的n个顶点,绕城堡外面建一个围墙,围住所有点,
并且墙与所有点的距离至少为L,求这个墙最小的长度
思路:最小长度=城堡顶点构成的凸包的总边长+半径为L的圆的周长
先用Graham算法求出凸包,再枚举其顶点求两两之间的边长,记得加上第一个顶点和最后一个顶点的边长
最后要输出四舍五入的整数结果,可以用double存,最后用%.0lf输出
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; struct stu { int x,y; }p[1010],s[1010]; int m,top; int chaji(struct stu p1,struct stu p2,struct stu p3) { return (p1.x-p2.x)*(p3.y-p2.y)-(p3.x-p2.x)*(p1.y-p2.y); } double dis(struct stu p1,struct stu p2) { return sqrt((p1.x-p2.x)*(p1.x-p2.x)*1.0+(p1.y-p2.y)*(p1.y-p2.y)); } int cmp(struct stu p1,struct stu p2) { int k; k=chaji(p1,p[0],p2); if(k>0||(k==0&&dis(p1,p[0])<dis(p2,p[0]))) return 1; return 0; } void graham() { struct stu t; int k=0,i; for(i=1;i<m;i++) if(p[i].y<p[k].y||(p[i].y==p[k].y&&p[i].x<p[k].x)) k=i; t=p[k]; p[k]=p[0]; p[0]=t; sort(p+1,p+m,cmp); s[0]=p[0]; s[1]=p[1]; top=1; for(i=2;i<m;i++){ while(top>=1&&chaji(s[top-1],s[top],p[i])>=0) top--; top++; s[top]=p[i]; } } int main() { int n,i; double sum; while(scanf("%d%d",&m,&n)!=EOF){ for(i=0;i<m;i++) scanf("%d%d",&p[i].x,&p[i].y); graham(); sum=dis(s[0],s[top])+2*3.1415926*n; for(i=1;i<=top;i++) sum+=dis(s[i-1],s[i]); printf("%.0lf\n",sum); } return 0; }
poj 1113 Wall (凸包),布布扣,bubuko.com
原文:http://blog.csdn.net/acm_code/article/details/38370049