zoukankan      html  css  js  c++  java
  • 凸包问题——Graham Scan

    Graham Scan 概述:

    对于凸多边形的定义不在这里做详细叙述,这里给出算法的实现原理。

    Step 1:

    找出x值最小的点的集合,从其中找出y值最小的点作为初始点

    Step 2:

    获得新序列后,p[n]=p[1]

    Step 3:

    把p[0],p[1],p[2]放入一个栈,从i=3循环到i=n-1,取栈顶两个元素和p[i]连线,如果未形成左旋,栈顶元素退栈,直到栈中元素仅剩两个。

    将p[i]压入栈。

    C++代码:

    #include <algorithm>
    #define MAX_N 100000000
    
    int top;//凸包的顶点个数
    typedef std::pair<int, int> point;
    int dis(point p1, point p2)//两点的距离的平方
    {
        return (p1.first - p2.first)*(p1.first - p2.first) + (p1.second - p2.second)*(p1.second - p2.second);
    }
    point p[MAX_N];
    //向量p0p1和向量p0p2的叉积
    int  multi(point p1, point p2, point p0)
    {
        //x1*y2-x2*y1
        return (p1.first - p0.first) * (p2.second - p0.second) - (p2.first - p0.first) * (p1.second - p0.second);
    }
    bool cmp(point a, point b)
    {
        //点b的极角更大
        if (multi(a, b, p[0]) > 0)
            return true;
        //共线
        if (multi(a, b, p[0]) == 0 && dis(a, p[0]) < dis(b, p[0]))
            return true;
        return false;
    }
    //Graham_scan的精华
    void Graham_scan(point p[], point stack[], int n)
    {
        int i, k = 0;
        top = 2;
        //寻找最下且偏左的点
        for (i = 1;i < n;i++)
            if (p[i].second < p[k].second || ((p[i].second == p[k].second) && (p[i].first < p[k].first)))
                k = i;
        //将该点指定为p[0];
        std::swap(p[0], p[k]);
        //按极角从小到大,距离偏短进行排序,此处注意p[0]
        std::sort(p[1], p[n - 1], cmp);
        //核心,方便起见,这里使用我们自建的stack
        stack[0] = p[0], stack[1] = p[1], stack[2] = p[2];
        for (i = 3;i < n;i++)
        {
            while (top > 1 && multi(p[i], stack[top], stack[top - 1]) >= 0)
                top--;
            stack[++top] = p[i];
        }
    }
     
  • 相关阅读:
    assign()与create()的区别
    ES6对象扩展——部分新的方法和属性
    ES6对象扩展——扩展运算符
    rest operater剩余操作符
    深拷贝和浅拷贝
    for in和for of的简单区别
    查询ES6兼容的网站
    ES6扩展——对象的扩展(简洁表示法与属性名表达式)
    滚动条设置样式
    marquee横向无缝滚动无js
  • 原文地址:https://www.cnblogs.com/cielosun/p/5654542.html
Copyright © 2011-2022 走看看