计算几何 ( 凸包 )——Wall ( HDU 1248 )

来源:互联网 发布:mac怎么查看隐藏文件夹 编辑:程序博客网 时间:2024/06/05 09:58
  • 题目链接
    http://acm.hdu.edu.cn/showproblem.php?pid=1348

  • 分析:
    给出N个点,求距离这N个点围成的多边形距离为L的围墙的周长。可以得出,这个周长就是多边形周长加上一个圆的周长。多半形周长可以先求出凸包点集,然后依次累加距离即可。然后这个题需要注意输出格式!最后一个输出数据不用加两个换行!!!

  • 题解:
    1.求凸包:

int cmp(point a, point b)  //水平排序{    if(a.x==b.x)return a.y<b.y;        return a.x<b.x;}int convex(int n, point P[], point res[])//n为总点数,P 为点集,res为输出凸包上点的点集{    sort(P, P+n,cmp);    int m=0,i,j,k;    //求得下凸包,逆时针    //已知凸包点m个,如果新加入点为i,则向量(m-2,i)必定要在(m-2,m-1)的逆时针方向才符合凸包的性质    //若不成立,则m-1点不在凸包上。    for(i=0;i<n;i++)    {        while(m>1&&multiply(res[m-1], P[i], res[m-2])<=0)            m--;        res[m++]=P[i];    }    k=m;    //求得上凸包    for(i=n-2;i>=0;i--)    {        while(m>k&&multiply(res[m-1],P[i],res[m-2])<=0)m--;        res[m++]=P[i];    }    if(n>1) m--;//起始点重复。    return m;}
  • AC代码:
#include <cstdio>#include <cstring>#include <cmath>#include <iostream>#include <algorithm>using namespace std;const double PI  = 3.14159265;int N, L;struct point{    double x;    double y;}P[1234],res[1234];int cmp(point a, point b)  //水平排序{    if(a.x==b.x)return a.y<b.y;        return a.x<b.x;}double multiply(point a, point b,point c)//向量积{    return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y);}int convex(int n, point P[], point res[])//n为总点数,P 为点集,res为输出凸包上点的点集{    sort(P, P+n,cmp);    int m=0,i,j,k;    //求得下凸包,逆时针    //已知凸包点m个,如果新加入点为i,则向量(m-2,i)必定要在(m-2,m-1)的逆时针方向才符合凸包的性质    //若不成立,则m-1点不在凸包上。    for(i=0;i<n;i++)    {        while(m>1&&multiply(res[m-1], P[i], res[m-2])<=0)            m--;        res[m++]=P[i];    }    k=m;    //求得上凸包    for(i=n-2;i>=0;i--)    {        while(m>k&&multiply(res[m-1],P[i],res[m-2])<=0)m--;        res[m++]=P[i];    }    if(n>1) m--;//起始点重复。    return m;}double dist(point p1,point p2)                // 返回两点之间欧氏距离{ return sqrt( (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y) )  ;}int main(){    int T;    scanf("%d", &T);    while(T--)    {        scanf("%d%d", &N, &L);        int t = 0;        while(t<N)        {            scanf("%lf%lf", &P[t].x, &P[t].y);            t++;        }        int len = convex(N, P, res);        double Length = PI * L * 2;        for(int i=0;i<len-1;i++)        {            Length += dist(res[i], res[i+1]);        }        Length += dist(res[len-1], res[0]);        printf("%.0lf\n", Length); //printf自带四舍五入        if(T) cout << endl;    }    return 0;}
0 0
原创粉丝点击