hdu 1348 Wall (凸包模板)

来源:互联网 发布:知乎 投资人 编辑:程序博客网 时间:2024/04/30 07:04
/* 题意: 求得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;}

0 0
原创粉丝点击