UVa 1303 - Wall(凸包)

来源:互联网 发布:鹏博士数据 编辑:程序博客网 时间:2024/05/18 03:01

求所给点的凸包每个顶点向外延伸半径为l的圆后所得图形的周长。
凸包周长模板题,求得凸包周长后加上以l为半径的圆的周长就是墙的长度。

#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>using namespace std;const int maxn=1010;struct point{    double x,y;}a[maxn],b[maxn];bool mult(point p0,point p1,point p2){    return (p1.x-p0.x)*(p2.y-p0.y)>=(p2.x-p0.x)*(p1.y-p0.y);}bool operator<(const point &p1,const point &p2){    return p1.y<p2.y||(p1.y==p2.y&&p1.x<p2.x);}int graham(point pnt[],int n,point res[]){    int i,len,top=1;    sort(pnt,pnt+n);    if(n==0) return 0;    res[0]=pnt[0];    if(n==1) return 1;    res[1]=pnt[1];    if(n==2) return 2;    res[2]=pnt[2];    for(i=2;i<n;i++){        while(top&&mult(pnt[i],res[top],res[top-1]))            top--;        res[++top]=pnt[i];    }    len=top;res[++top]=pnt[n-2];    for(i=n-3;i>=0;i--){        while(top!=len&&mult(pnt[i],res[top],res[top-1]))            top--;        res[++top]=pnt[i];    }    return top;}int main(){    int t;scanf("%d",&t);    while(t--){        int n,l;scanf("%d%d",&n,&l);        memset(a,0,sizeof(a));        memset(b,0,sizeof(b));        for(int i=0;i<n;++i) scanf("%lf%lf",&a[i].x,&a[i].y);        int k=graham(a,n,b);        double ans=0;        for(int i=0;i<k-1;++i)            ans+=sqrt((b[i].x-b[i+1].x)*(b[i].x-b[i+1].x)+(b[i].y-b[i+1].y)*(b[i].y-b[i+1].y));        if(k>2) ans+=sqrt((b[k-1].x-b[0].x)*(b[k-1].x-b[0].x)+(b[k-1].y-b[0].y)*(b[k-1].y-b[0].y));        ans+=2*acos(-1)*l;        printf("%.0lf\n",ans);        if(t) printf("\n");    }    return 0;}
0 0