题意:给定多边形城堡的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;
}