凸包--Graham扫描法
一直听大佬们说:凸包、凸包、凸包
一直不会。。。。。
然后。。。。
今天考试,考了一道计算几何的简单题。。。。
这,,,还是学一下吧。。
然后考试现场学习一下凸包算法。
先理解一下凸包是啥东西。
看看这张图
解释一下凸包是什么
如果你有一堆点(原谅我画的很凌乱)
那么,找到一个点集
依次连接这些点
使他们形成一个凸多边形
并且所有的点都包括在这个多边形的内部或者边上
这个多边形就是一个凸包(我写的肯定一点也不严谨)
不管怎么样,就先这样理解一下吧。。。。。。
凸包是啥应该不难理解,那么,给你一堆点,怎么求凸包?
这种东西。。。。。
先大概说一下把。。。
首先找到最靠近左下的那个点,这个点一定在凸包上(不难理解吧。。。画个图就知道了)
以这个点为极点,其他点按照极角排序
然后按照顺序依次访问所有点,判断可行性
这样子干说真是虚无缥缈的东西。。。。。。
画图来解释
这是一片点。
找到最靠近左下的一个点
其他的点按照极角排序
然后把1丢到凸包的栈里面,准备开始扫描
检查2号点是否在1的一侧,(检查一下是不是凸多边形)
这里检查到2号可行,先加入到栈中
检查到3更加靠近外侧(如果加入3号就会形成凹多边形,显然3在凸包中,而2不在)
然后把2号点弹出栈,判断1号和3号节点的关系(同判断2号)
依次这么判断,最后所有凸包上的点都会在栈中
这样子算法的步骤很显然了。
继续解决一些细节上的问题(貌似就一个把。。。。)
怎么计算一个节点是否在前一个点的一侧。。。。
(我说的好不专业。。。我自己都不知道该怎么说一些名词。。。就将就着理解一下吧。。。)
我们先拿几个点出来
其中1,2,3是当前在凸包的栈中的点,4号节点是需要判断的点
那么,我们需要从栈中拿最上方的两个点(2和3节点)
把他们连接起来,再把2和4连接起来(怎么连接?我是不会说直接用向量的坐标表示就可以了)
计算一下两个向量的叉积。。
哈,叉积。。。
解释一下吧。。
假设2到3的向量是a(x1,y1)
2到4的向量是b(x2,y2)
那么,计算一下它们的叉积,也就是x1y2-x2y1
换种方法来表示就是。
|a|·|b|·sin<a,b>
(所以说叉积也可以用来求出三角形的面积~这个以后还会用到的)
如果,这两个向量的叉积≥0 证明这两个向量平行或者夹角是个锐角
也就证明了3号节点此时一定不再凸包上(因为连接2和4之后3在凸包内侧了)
把3号节点弹出栈,继续重复上面的步骤即可。
感觉我说的有点小复杂诶。。。。
这个东东多画点图就会理解的
如果还是不太清楚,可以看一看代码。
struct Node
{
int x,y;
}p[MAX],S[MAX];//p储存节点的位置,S是凸包的栈
inline bool cmp(Node a,Node b)//比较函数,对点的极角进行排序
{
double A=atan2((a.y-p[1].y),(a.x-p[1].x));
double B=atan2((b.y-p[1].y),(b.x-p[1].x));
if(A!=B)return A<B;
else return a.x<b.x; //这里注意一下,如果极角相同,优先放x坐标更小的点
}
long long Cross(Node a,Node b,Node c)//计算叉积
{
return 1LL*(b.x-a.x)*(c.y-a.y)-1LL*(b.y-a.y)*(c.x-a.x);
}
void Get()//求出凸包
{
p[0]=(Node){INF,INF};int k;
for(int i=1;i<=n;++i)//找到最靠近左下的点
if(p[0].y>p[i].y||(p[0].y==p[i].y&&p[i].x<p[0].x))
{p[0]=p[i];k=i;}
swap(p[k],p[1]);
sort(&p[2],&p[n+1],cmp);//对于剩余点按照极角进行排序
S[0]=p[1],S[1]=p[2];top=1;//提前在栈中放入节点
for(int i=3;i<=n;)//枚举其他节点
{
if(top&&Cross(S[top-1],p[i],S[top])>=0)
top--;//如果当前栈顶不是凸包上的节点则弹出
else S[++top]=p[i++];//加入凸包的栈中
}
//底下这个玩意用来输出凸包上点的坐标
//for(int i=0;i<=top;++i)
// printf("(%d,%d)\n",S[i].x,S[i].y);
}
接下来找一道简单点的例题
HDU 1392
这道题目就是求出凸包然后计算周长,很简单的题目,去试试吧。。
凸包--Graham扫描法的更多相关文章
- [hdu contest 2019-07-29] Azshara's deep sea 计算几何 动态规划 区间dp 凸包 graham扫描法
今天hdu的比赛的第一题,凸包+区间dp. 给出n个点m个圆,n<400,m<100,要求找出凸包然后给凸包上的点连线,连线的两个点不能(在凸包上)相邻,连线不能与圆相交或相切,连线不能相 ...
- 【计算几何初步-凸包-Graham扫描法-极角序】【HDU1348】 WALL
Wall Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...
- 凸包算法(Graham扫描法)详解
先说下基础知识,不然不好理解后面的东西 两向量的X乘p1(x1,y1),p2(x2,y2) p1Xp2如果小于零则说明 p1在p2的逆时针方向 如果大于零则说明 p1在p2的顺时针方向 struct ...
- 【BZOJ-1670】Building the Moat护城河的挖掘 Graham扫描法 + 凸包
1670: [Usaco2006 Oct]Building the Moat护城河的挖掘 Time Limit: 3 Sec Memory Limit: 64 MBSubmit: 464 Solv ...
- 计算几何 : 凸包学习笔记 --- Graham 扫描法
凸包 (只针对二维平面内的凸包) 一.定义 简单的说,在一个二维平面内有n个点的集合S,现在要你选择一个点集C,C中的点构成一个凸多边形G,使得S集合的所有点要么在G内,要么在G上,并且保证这个凸多边 ...
- Graham 扫描法找凸包(convexHull)
凸包定义 通俗的话来解释凸包:给定二维平面上的点集,凸包就是将最外层的点连接起来构成的凸多边型,它能包含点集中所有的点  Graham扫描法 由最底的一点 \(p_1\) 开始(如果有多个这样的点, ...
- 关于graham扫描法求凸包的小记
1.首先,凸包是啥: 若是在二维平面上,则一般的,给定二维平面上的点集,凸包就是将最外层的点连接起来构成的凸多边型,它能包含点集中所有的点. ───────────────────────────── ...
- Graham扫描法 --求凸包
前言: 首先,什么是凸包? 假设平面上有p0~p12共13个点,过某些点作一个多边形,使这个多边形能把所有点都“包”起来.当这个多边形是凸多边形的时候,我们就叫它“凸包”.如下图: 然后,什么是凸包 ...
- (模板)poj1113(graham扫描法求凸包)
题目链接:https://vjudge.net/problem/POJ-1113 题意:简化下题意即求凸包的周长+2×PI×r. 思路:用graham求凸包,模板是kuangbin的. AC code ...
随机推荐
- [Python Study Notes]异常处理
正则表达式 python提供了两个非常重要的功能来处理python程序在运行中出现的异常和错误.你可以使用该功能来调试python程序. 异常处理 断言(Assertions) python标准异常 ...
- bzoj 3048[Usaco2013 Jan]Cow Lineup 思想,乱搞 stl
3048: [Usaco2013 Jan]Cow Lineup Time Limit: 2 Sec Memory Limit: 128 MBSubmit: 237 Solved: 168[Subm ...
- .net core 2.0学习笔记(二):部署到Windows和Liunx系统
.Net Core最大的亮点就是跨平台了,下面介绍下在Windows下和Liunx下的部署. 首先发布项目文件,点击网站项目右键 发布: 从下图发布的文件图片可以看出,不像以前bin目录下有很多dll ...
- 关于HTTP,你知道哪些?
HTTP简介 HTTP 的全称是 Hypertext Transfer Protocol,超文本传输协议 规定客户端和服务器之间的数据传输格式 让客户端和服务器能有效地进行数据沟通 HTTP 协议是网 ...
- MySQL 日志的类型
日志文件对于一个服务器来说是非常重要的,它记录着服务器的运行信息,许多操作都会写日到日志文件,通过日志文件可以监视服务器的运行状态及查看服务器的性能,还能对服务器进行排错与故障处理,MySQl中有六种 ...
- es6之let和const命令的一些笔记
let和const命令 let命令 基本用法 let命令用来声明变量,声明的变量只在命令所在的代码块内有效.for循环中很适合使用let命令. 有必要理解的例子: var a = []; for (v ...
- 【Learning】 动态树分治
简介 动态树分治整体上由点分治发展而来. 点分治是统计树上路径,而动态树分治用来统计与点有关的树上路径,比如多次询问某一些点到询问点的距离和. 前置知识就是点分治. 做法 众所周知,点分树(点分治中重 ...
- python-scrapy的编码问题
在学习scrapy中,遇到编码问题还是很头痛的问题的.由于对于语言的对不熟悉,加上不会思考的去解决问题.这样盲目的实践似乎就是在浪费时间. 用心思考一下是非常重要的一个过程,在没有办法前进的时候,先学 ...
- 使用jsoup抓取新闻信息
1,jsoup简介 jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址.HTML文本内容.它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和 ...
- winhex中判断+MBR+DBR+EBR方法
[/hide] 扇区开始描述). 用 winhex 做U盘免疫AUTO.INF 用WinHex制作无法修改的AutoRun.inf文件 在我们日常工作中,经常需要使用闪存(也称为U盘或者优盘)主要是A ...