博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Graham凸包算法简介
阅读量:6787 次
发布时间:2019-06-26

本文共 2166 字,大约阅读时间需要 7 分钟。

凸包真是一个神奇的算法。。


概念

  • 凸包,我理解为凸多边形
  • 叉积 对于向量AB和向量BC,记向量AB*向量BC = AB * BC * sin ∠ABC,而叉积的绝对值其实就是S△ABC/2

对于平面上的一些点,我们要求凸包上所有的点,可以使用Graham算法 时间复杂度O(nlogn)


思路

先找到最左下的点,把其他的点按叉积排序。然后维护一个堆栈,每次利用叉积和栈顶比较判断当前枚举到的点是否是凸包上的点,是则弹出栈顶元素

具体算法

  • 周长

    直接所有相邻两点距离相加

  • 面积

    多边形面积直接利用公式,用叉积计算


常熟巨大的丑陋代码

# include 
# include
# include
# include
# include
# include
# define RG register# define IL inline# define ll long long# define mem(a, b) memset(a, b, sizeof(a))# define Min(a, b) (((a) > (b)) ? (b) : (a))# define Max(a, b) (((a) < (b)) ? (b) : (a))# define Sqr(a) ((a) * (a))using namespace std;const int MAXN = 50001;int n, top;struct Point{ double x, y, len;} p[MAXN], Point_A, s[MAXN]; //最左下的点 //求叉积(向量ab,向量ac) IL double Cross(Point a, Point b, Point c){ return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);}IL double Dis(Point a, Point b){ return sqrt(Sqr(a.x - b.x) + Sqr(a.y - b.y));}//极角排序 IL bool Cmp(Point a, Point b){ RG double x = Cross(Point_A, a, b); if(x > 0) return 1; else if(x < 0) return 0; a.len = Dis(Point_A, a); b.len = Dis(Point_A, b); return a.len < b.len;}//查找起始点,最左下IL void Find(){ RG int temp = 0; RG Point a = p[1]; for(RG int i = 2; i <= n; i++) if(p[i].y < a.y || p[i].y == a.y && p[i].x < a.x){ a = p[i]; temp = i; } p[temp] = p[1]; p[1] = a; Point_A = a;//保存起始点}//求凸包周长IL double Length(){ RG double sum = 0; for(RG int i = 1; i <= top; i++) sum += Dis(s[i - 1], s[i]); return sum;}//计算面积IL double Area(){ RG double sum = 0; for(RG int i = 1; i < top - 1; i++) sum += Cross(s[0], s[i], s[i + 1]); sum = fabs(sum) / 2; return sum;}IL void Graham(){ Find(); sort(p + 2, p + n + 1, Cmp); s[0] = p[1]; s[1] = p[2]; for(RG int i = 3; i <= n; i++){ while(Cross(s[top - 1], s[top], p[i]) <= 0 && top) top--; s[++top] = p[i]; } s[++top] = p[1];}int main(){ while(~scanf("%d", &n) && n){ top = 1; for(RG int i = 1; i <= n; i++) scanf("%lf%lf", &p[i].x, &p[i].y); Graham(); cout << top << " " << length() << " " << Area() << endl; } return 0;}

板子题 1.Surround the Trees HDU - 1392 2.Cows POJ - 3348

转载于:https://www.cnblogs.com/cjoieryl/p/8206404.html

你可能感兴趣的文章
ubuntu日常使用心得(随时更新中。。。)
查看>>
Java 多线程回顾
查看>>
二、nginx服务器基础配置命令
查看>>
TEMP表空间之Ogg复制进程占用
查看>>
java中的构造函数总结
查看>>
windows下kangle虚拟主机-安装mysql教程及心得
查看>>
我的友情链接
查看>>
ios中SQLite的重构封装
查看>>
centos 搭建 nagios 监控系统.
查看>>
管理禁忌小记录(一)
查看>>
遍历接口信息
查看>>
Dell R710 服务器更新windows server 2012的相关问题
查看>>
编程中最神奇的数字,你知道吗?
查看>>
数据可视化:柱状图、雷达图等六种基本图表的特点和适用场合
查看>>
选择器 :gt(index)
查看>>
notes on python
查看>>
kafa
查看>>
资源 | Feature Tools:可自动构造机器学习特征的Python库
查看>>
linux Shell 中常用的条件判断
查看>>
angular 动态设置blob链接给 ng-href时遇到unsafe 解决方案
查看>>