poj 1113 Wall (凸包)

链接:poj 1113

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


posted @ 2016-01-11 19:03  lcchuguo  阅读(204)  评论(0编辑  收藏  举报