• hdu1392Surround the Trees(凸包)


    凸包概念:坐标上有好多好多点,把外围的点连起来,所有点都包括在线上或者里面,此时周长最小。看起来每个角凸出去,简称凸包。

    顺序:1.找基点 2.自定义按其他点和基点之间的斜率排序 3.按顺序找出符合条件的点压进凸包集合

    https://vjudge.net/problem/HDU-1392

    题意:有好多树,从最外围围起来,篱笆要多长?

    思路:凸包模板题,记录代码

    #include<stdio.h>
    #include<math.h>
    #include<algorithm>///sort需要的函数
    using namespace std;
    
    struct node
    {
        int x;
        int y;
    };
    node p[105];
    node tu[105];
    int n,top;
    ///叉积是矢量概念,如果结果大于0,p0p1在p0p2的顺时针方向
    double chaji(node p0,node p1,node p2)
    {   ///叉积公式=x1*y2-x2*y1,叉积是矢量概念,如果结果大于0,p0p1在p0p2的顺时针方向
        return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
    }   ///叉积的绝对值是三个点围成面积的一半
    
    double dis(node p1,node p2)
    {
        return sqrt( (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y) );
    }
    
    bool cmp(node p1,node p2)///比较函数,只能两两相比
    {
        double z=chaji(p[0],p1,p2);
        if( z>0 || (z==0&&dis(p[0],p1)<dis(p[0],p2)) )
            return true;///返回真,则p1排在p2前
        return false;
    }
    
    void Graham()///从基点开始寻找外围的点
    {//葛立恒发明的算法
        double z;
        tu[0]=p[0];
        tu[1]=p[1];///这两个点总会放进凸包里
        top=1;
        for(int i=2;i<n;i++)
        {
            while( chaji(tu[top-1],tu[top],p[i])<0 )///通过p[i]判断tu[top]是不是符合要求
                top--;///top-1,继续判断,直到找到符合条件的top,下面会覆盖掉原来的不符合条件的下标内容
            top++;
            tu[top]=p[i];
        }
        ///最后一个点在基点和倒数第二点的连线之外,必然是凸出去的
    }
    int main()
    {
        while(scanf("%d",&n) && n)
        {
            for(int i=0;i<n;i++)///输入杂乱无章的各点坐标
                scanf("%d%d",&p[i].x,&p[i].y);
            if(n==1)
                {printf("0\n");continue;}
            else if(n==2)
                {printf("%.2lf\n",dis(p[0],p[1]));continue;}
            int k=0;
            for(int i=0;i<n;i++)
                if( p[k].y>p[i].y || (p[k].y==p[i].y&&p[k].x>p[i].x) )
                    k=i; ///找基点下标,越下越左的
            swap(p[0],p[k]);///目前还没有排序,只要确定基点,其他随便换
            sort(p+1,p+n,cmp);///按自定义的排序方法排序
            Graham();
            double len=0;///算凸包外面的长度
            for(int i=0;i<top;i++)
                len += dis(tu[i],tu[i+1]);
            len += dis(tu[0],tu[top]);
            printf("%.2f\n",len);
        }
    }
  • 相关阅读:
    week8-A-区间选点
    C-TT的美梦
    B-dijkstra-TT的旅行日记
    week7-A-Floyd-TT的魔法猫
    Codeforces 437B The Child and Set (贡献+贪心)
    Codeforces 1236B Alice and the List of Presents(贡献)
    2019 牛客多校 第八场 B Beauty Values (贡献)
    Codeforces 1244G Running in Pairs 序列交换(贪心)
    Codeforces 1244F Chips(环修改,思维题)
    BZOJ 3784 树上的路径(点分治+ST+堆+贪心)待处理
  • 原文地址:https://www.cnblogs.com/shoulinniao/p/9464457.html
Copyright © 2020-2023  润新知