码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 1348 Wall (凸包模板)

时间:2015-07-24 20:53:37      阅读:119      评论:0      收藏:0      [点我收藏+]

标签:

/*
 题意:

 求得n个点的凸包,然后求与凸包相距l的外圈的周长。


 答案为n点的凸包周长加上半径为L的圆的周长

*/
# include <stdio.h>
# include <math.h>
# include <string.h>
# include <algorithm>
using namespace std;
# define PI acos(-1.0)
struct node
{
    int x;
    int y;
};
node a[1010],res[1010];
bool cmp(node a1,node a2)
{
    if(a1.x==a2.x)
        return a1.y<a2.y;
    return a1.x<a2.x;
}
int cross(node a1,node a2,node a3)
{
    return (a1.x-a3.x)*(a2.y-a3.y)-(a2.x-a3.x)*(a1.y-a3.y);
}
int convex(int n)//求凸包上的点
{
    int m=0,i,j,k;
    sort(a,a+n,cmp);
     //求得下凸包,逆时针
    //已知凸包点m个,如果新加入点为i,则向量(m-2,i)必定要在(m-2,m-1)的逆时针方向才符合凸包的性质
    //若不成立,则m-1点不在凸包上。
    for(i=0;i<n;i++)
    {
        while(m>1&&cross(res[m-1],a[i],res[m-2])<=0)
            m--;
        res[m++]=a[i];
    }
    k=m;
    //求得上凸包
    for(i=n-2;i>=0;i--)
    {
        while(m>k&&cross(res[m-1],a[i],res[m-2])<=0)
            m--;
        res[m++]=a[i];
    }
    if(n>1)
        m--;
    return m;
}
double length(node a1,node a2)
{
    return sqrt(1.0*(a1.x-a2.x)*(a1.x-a2.x)+(a1.y-a2.y)*(a1.y-a2.y));
}
int main()
{
    int t,n,i,L,m;
    while(~scanf("%d",&t))
    {
        while(t--)
        {
            scanf("%d%d",&n,&L);
            for(i=0;i<n;i++)
                scanf("%d%d",&a[i].x,&a[i].y);
            m=convex(n);
            double ans=0;
            for(i=1;i<m;i++)
                ans+=length(res[i],res[i-1]);
            ans+=length(res[0],res[m-1]);
            ans+=2*PI*L;
            printf("%.0lf\n",ans);
            if(t)
                printf("\n");
        }
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

hdu 1348 Wall (凸包模板)

标签:

原文地址:http://blog.csdn.net/lp_opai/article/details/47045481

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!