ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

[算法笔记]凸包问题

2022-03-06 19:03:32  阅读:214  来源: 互联网

标签:ch Point double 笔记 凸包 算法 Pn


二维凸包问题 Andrew算法

写在前面:

本文参考自:刘汝佳《算法竞赛入门经典-训练之南》

介绍:

凸包:把给定点包围在内部的、面积最小的凸多边形。

Andrew算法是Graham算法的变种,速度更快,数值稳定性也更好。

算法实现:

  1. 首先把全部点按照x从小到打排序(x相等,则按照y从小到大排序),删除重复点后得到点序列P1...Pn
    bool operator<(const Point &p1, const Point &p2)//重载<,后续使用sort
    {
        return p1.x < p2.x || (p1.x == p2.x && p1.y < p2.y);
    }
  2. 把P1,P2放入凸包中,凸包中的点使用栈存储。
  3. 从P3开始,当下一个点在凸包当前前进方向左边的时候继续。
  4. 否则依次删除近期增加凸包的点,直到新点在左边。

如图,新点P18在当前前进方向P10P15的右边(使用叉积推断),因此须要从凸包上删除点P15和P10。让P8的下一个点为P18。反复该过程直到碰到最右边的Pn,求出下凸包即凸包的下轮廓。然后从Pn反过来反复该步骤求出上凸包,合并起来后就是完整的凸包。

该算法扫描为O(n)复杂度,排序O(nlogn)。

 

完整代码:

#include<bits/stdc++.h>

using namespace std;

struct Point {
    double x, y;

    Point(double x = 0, double y = 0) : x(x), y(y){};
} p[10005], ch[10005];

int n;

bool operator<(const Point &p1, const Point &p2) {
    return p1.x < p2.x || (p1.x == p2.x && p1.y < p2.y);
}

Point operator-(Point A, Point B) {
    return Point(A.x - B.x, A.y - B.y);
}

double Cross(Point A, Point B) {//两点交叉积
    return A.x * B.y - A.y * B.x;
}

int ConvexHull() {
    sort(p, p + n);
    int m = 0;
    for (int i = 0; i < n; i++) {
        while (m > 1 && Cross(ch[m - 1] - ch[m - 2], p[i] - ch[m - 2]) <= 0)m--;
        ch[m++] = p[i];
    }
    int k = m;
    for (int i = n - 2; i >= 0; i--) {
        while (m > k && Cross(ch[m - 1] - ch[m - 2], p[i] - ch[m - 2]) <= 0)m--;
        ch[m++] = p[i];
    }
    if (n > 1)m--;
    return m;
}

int main() {
    cin >> n;
    for (int i = 0; i < n; i++) {
        double x, y;
        cin >> x >> y;
        p[i] = Point(x, y);
    }
    return 0;
}

 

标签:ch,Point,double,笔记,凸包,算法,Pn
来源: https://www.cnblogs.com/liubaili/p/15973008.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有