zoukankan      html  css  js  c++  java
  • 凸包略解

    写篇博客证明窝没有在期末考中AFO

    由于笔者太菜,所以只会Andrew算法

    其他的算法珂以康这位dalao的博客

    Andrew算法

    Andrew算法是Graham扫描法的变种,Andrew更快,更稳定

    先把所有的点按照x从小到大(x相等时,y也按从小到大)排序

    删除重复点(依据题目而确定是否要这个步骤)

    画几个图,会发现第一个点和最后一个点都一定在凸包中

    我们先从前向后扫描,维护下凸壳

    再从后向前扫描,维护上凸壳

    这样就能求出凸包,复杂度为(O(N log N))

    完整代码(Luogu P2742 【模板】二维凸包 / [USACO5.1]圈奶牛Fencing the Cows

    #include <bits/stdc++.h>
    #define db double
    #define vec Point
    #define N 10005
    using namespace std;
    struct Point{
        db x,y;
        Point(db x=0,db y=0):x(x),y(y) {}
    };
    vec operator - (Point a,Point b){
        return vec(a.x-b.x,a.y-b.y);
    }
    bool operator < (const Point& a,const Point& b){
        return a.x<b.x||(a.x==b.x&&a.y<b.y);
    } 
    Point p[N],ch[N];
    inline db cross(register vec a,register vec b)
    {
        return a.x*b.y-a.y*b.x;
    }
    inline db dis(register Point a,register Point b)
    {
        return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    }
    int main()
    {
        int n;
        scanf("%d",&n);
        for(register int i=1;i<=n;++i)
            scanf("%lf%lf",&p[i].x,&p[i].y);
        sort(p+1,p+1+n);
        int m=1;
        for(register int i=1;i<=n;++i)
        {
            while(m>2&&cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0)
                --m;
            ch[m++]=p[i];
        }
        int k=m;
        for(register int i=n-1;i;--i)
        {
            while(m>k&&cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0)
                --m;
            ch[m++]=p[i];
        }
        db ans=0;
        for(register int i=1;i<m-1;++i)
            ans+=dis(ch[i],ch[i+1]);	
        printf("%.2lf",ans);
        return 0;
    }
    
  • 相关阅读:
    常用工具
    H5页面验收流程及性能验收标准
    埋点数据测试
    提高效率的必备工具
    移动APP安全测试
    Response响应相关
    AES加密解密
    Requests模块
    爬虫入门
    【CMDB】API传输验证
  • 原文地址:https://www.cnblogs.com/yzhang-rp-inf/p/10300958.html
Copyright © 2011-2022 走看看