计算几何之凸包模板
来源:互联网 发布:网络征文比赛2017 编辑:程序博客网 时间:2024/06/07 16:03
凸包复习
几何专题刷了有大半年了,突然发现以前学的竟然忘的差不多了,下午又花了点时间复习一下,感觉挺简单的(全是靠模板。。
资料上没有适合自己的模板,于是复习一下自己整理一下模板。
先来接触点预备函数:
一、 点的定义:
int n,tot;//n为二维平面上点的个数,tot为凸包上点的个数struct node{ int x,y;}a[N],p[N];//p[]用来储存凸包
二、距离公式:
double dis(node a,node b){ return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);}三、叉积:返回结果为正说明p2在向量p0p1的左边(三点构成逆时针方向);为负则相反;为0则三点共线(叉积的性质很重要)
double multi(node p0,node p1,node p2){ return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);}四、极角排序:极角排序是根据坐标系内每一个点与x轴所成的角,逆时针比较,。按照角度从小到大的方式排序。
int cmp(node p1,node p2)//极角排序;{ int x=multi(p1,p2,a[0]); if(x>0||(x==0&&dis(p1,a[0])<dis(p2,a[0]))) return 1; return 0;}graham 算法:O(nlogn)
void Graham(){ int k=0; for(int i=0;i<n;i++) if(a[i].y<a[k].y||(a[i].y==a[k].y&&a[i].x<a[k].x)) k=i; swap(a[0],a[k]); sort(a+1,a+n,cmp); tot=2,p[0]=a[0],p[1]=a[1]; for(int i=2;i<n;i++) { while(tot>1&&multi(p[tot-1],p[tot-2],a[i])>=0) tot--; p[tot++]=a[i]; }}
以上连接起来就是求凸包的模板。
光有代码不行,还得懂原理
附一篇较好的博客:传送门
看懂了那篇博客基本上凸包就已经会了。
先用一个经典问题来引入吧: 在一片有限区域的草坪上有n个木桩(n>=3),现在要求用一根绳子将这些木桩围起来,求所需绳子的最短周长。
以上问题中绳子所围成的图形就是一个凸包。要求周长,那么必须先要求出绳子接触了哪些木桩。
求凸包有若干种方法,这里只介绍Graham算法。
大致思路:先确定凸包上一个点,再用这个点作为参照将剩余的点进行极角排序,根据性质可以得到凸包上的第二个点,再用已知的凸包上的点利用叉积的性质进行确定下一个点,直到围成一个凸包。
① 先确定凸包上的一个点,我们知道横纵坐标最大或最小的点肯定在凸包上,我们就选取纵坐标最小的点作为第一个点,如果有多个纵坐标最小的点怎么办呢,我们选取横坐标最小的点。这是为极角排序做准备。
② 极角排序:上面提到了极角排序的定义,我们可以以选取的第一个点p0作为原点(参照),其他点与p0点的连线与x轴的夹角进行排序,如果夹角相同怎么办呢,按与p0的距离排序,这一步考验对叉积的性质利用。
③ 除了p0,排序后的第一个点p1和最后一个点一定是凸包上的点,想想为什么。这样我们就得到了p0,p1,我们把它们放入栈里,现在用p0,p1来确定p2(栈顶的两个点来确定下一个点),还是用叉积的性质,栈顶两个点连成线(向量),看当前点是在直线的左边还是右边,如果在右边,说明栈顶的那个点不是凸包上的点,退栈即可,然后重复判断栈顶两个元素与当前元素的关系;反之,则说明当前点是凸包上的点。
④ 将当前点入栈,如果当前点不是凸包上的点,后面的点自然会将这个点gank。对下一个点进行相同的操作。最后栈中的点就是凸包上的点啦。
详细请参考上面代码。
推荐几道例题吧:
NYOJ-78 圈水池 入门凸包输出点
POJ-2007 Scrambled Polygon 求凸包并且按原点为第一点的逆时针方向输出
HDU-1392 Surround the Trees 入门求凸包周长
POJ-3348 Cows 入门求面积
POJ-2187 Beauty Contest 旋转卡壳求平面最远点对
POJ-1228 Grandpa's Estate 稳定凸包
POJ-1696 Space Ant 凸包应用(德黑兰赛区好题 )
POJ-1113 Wall 凸包简单应用(推荐)
- 计算几何之凸包模板
- 计算几何 --- 凸包 模板
- 计算几何之凸包
- 二维计算几何模板--多边形/凸包
- 计算几何模板——凸包
- 计算几何学习笔记之凸包
- <模板><计算几何>凸包及其基本算法
- uva 10652 凸包 + 更新版计算几何模板
- POJ1113 计算几何--整形凸包模板周长
- 计算几何-凸包
- [计算几何]凸包算法
- 计算几何-凸包问题
- 计算几何凸包详解
- 计算几何之凸包_卷包裹算法
- 计算几何之凸包----Graham扫描法
- 计算几何之凸包(三) {旋转卡壳初步}
- 计算几何之二维三维凸包算法
- 算法学习笔记之计算几何--平面凸包
- 微信小程序-navigator 跳转url传递参数
- Android自定义Dialog
- (26)抽象类引入、特点、和一般类区别、抽象继承练习
- JavaWeb随心笔记(1)
- 三、C_base——常用stdio.h函数
- 计算几何之凸包模板
- Java程序员学习路线图参考
- Scanner类的匹配失败问题
- 基础sql语句执行顺序的重要性
- Privacy policy
- Maven中央仓库地址和Nexus 下载地址
- Go实战--golang中读写文件的几种方式
- FSM有限状态机
- python 编程中要注意的事情