Graham扫描法 --求凸包
前言:
首先,什么是凸包?
假设平面上有p0~p12共13个点,过某些点作一个多边形,使这个多边形能把所有点都“包”起来。当这个多边形是凸多边形的时候,我们就叫它“凸包”。如下图:
然后,什么是凸包问题?
我们把这些点放在二维坐标系里面,那么每个点都能用 (x,y) 来表示。
现给出点的数目13,和各个点的坐标。求构成凸包的点?
Graham扫描法
时间复杂度:O(n㏒n)
思路:Graham扫描的思想和Jarris步进法类似,也是先找到凸包上的一个点,然后从那个点开始按逆时针方向逐个找凸包上的点,但它不是利用夹角。
步骤:
- 把所有点放在二维坐标系中,则纵坐标最小的点一定是凸包上的点,如图中的P0。
- 把所有点的坐标平移一下,使 P0 作为原点,如上图。
- 计算各个点相对于 P0 的幅角 α ,按从小到大的顺序对各个点排序。当 α 相同时,距离 P0 比较近的排在前面。例如上图得到的结果为 P1,P2,P3,P4,P5,P6,P7,P8。我们由几何知识可以知道,结果中第一个点 P1 和最后一个点 P8 一定是凸包上的点。
(以上是准备步骤,以下开始求凸包)
以上,我们已经知道了凸包上的第一个点 P0 和第二个点 P1,我们把它们放在栈里面。现在从步骤3求得的那个结果里,把 P1 后面的那个点拿出来做当前点,即 P2 。接下来开始找第三个点: - 连接P0和栈顶的那个点,得到直线 L 。看当前点是在直线 L 的右边还是左边。如果在直线的右边就执行步骤5;如果在直线上,或者在直线的左边就执行步骤6。
- 如果在右边,则栈顶的那个元素不是凸包上的点,把栈顶元素出栈。执行步骤4。
- 当前点是凸包上的点,把它压入栈,执行步骤7。
- 检查当前的点 P2 是不是步骤3那个结果的最后一个元素。是最后一个元素的话就结束。如果不是的话就把 P2 后面那个点做当前点,返回步骤4。
最后,栈中的元素就是凸包上的点了。
以下为用Graham扫描法动态求解的过程:
代码实现:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include <math.h>
#include <stdio.h>
#include <algorithm>
using namespace std;
struct point
{
long long x;
long long y;
} P[],S[]; //P 中存点,S模拟栈存凸包的点; long long xx;
long long yy; // 计算各个点相对于 P0 的幅角 α ,按从小到大的顺序对各个点排序。当 α 相同时,距离 P0 比较近的排在前面。
bool cmp(struct point a,struct point b)
{
if(atan2(a.y-yy,a.x-xx)!=atan2(b.y-yy,b.x-xx))
return (atan2(a.y-yy,a.x-xx))<(atan2(b.y-yy,b.x-xx));
return a.x<b.x;
} //叉积判断点的位置
long long CJ(long long x1,long long y1,long long x2,long long y2)
{
return (x1*y2-x2*y1);
} long long Compare(struct point a,struct point b,struct point c)
{
return CJ((b.x-a.x),(b.y-a.y),(c.x-a.x),(c.y-a.y));
} int main()
{
int n,i,j;
while(~scanf("%d",&n))
{
int top = ;
yy = +;
for(i=;i<n;i++)
{
scanf("%lld%lld",&P[i].x,&P[i].y);
if(P[i].y<yy)
{
yy = P[i].y;
xx = P[i].x;
j = i;
}
}
P[j] = P[];
sort(P+,P+n,cmp);
S[].x = xx;
S[].y = yy;
S[] = P[];
for(i = ;i<n;)
{
if(top&&(Compare(S[top-],S[top],P[i])<)) top--;
else S[++top] = P[i++];
}
for(i=;i<=top;i++)
printf("%lld %lld\n",S[i].x,S[i].y);
}
return ;
}
Graham扫描法 --求凸包的更多相关文章
- (模板)poj1113(graham扫描法求凸包)
题目链接:https://vjudge.net/problem/POJ-1113 题意:简化下题意即求凸包的周长+2×PI×r. 思路:用graham求凸包,模板是kuangbin的. AC code ...
- 关于graham扫描法求凸包的小记
1.首先,凸包是啥: 若是在二维平面上,则一般的,给定二维平面上的点集,凸包就是将最外层的点连接起来构成的凸多边型,它能包含点集中所有的点. ───────────────────────────── ...
- 使用Graham扫描法求二维凸包的一个程序
#include <iostream> #include <cstring> #include <cstdlib> #include <cmath> # ...
- Graham 扫描法找凸包(convexHull)
凸包定义 通俗的话来解释凸包:给定二维平面上的点集,凸包就是将最外层的点连接起来构成的凸多边型,它能包含点集中所有的点  Graham扫描法 由最底的一点 \(p_1\) 开始(如果有多个这样的点, ...
- [BZOJ1069][SCOI2007]最大土地面积(水平扫描法求凸包+旋转卡壳)
题意:在某块平面土地上有N个点,你可以选择其中的任意四个点,将这片土地围起来,当然,你希望这四个点围成. 的多边形面积最大.n<=2000. 先求凸包,再枚举对角线,随着对角线的斜率上升,另外两 ...
- nyoj-78-圈水池(Graham算法求凸包)
题目链接 /* Name:nyoj-78-圈水池 Copyright: Author: Date: 2018/4/27 9:52:48 Description: Graham求凸包 zyj大佬的模板, ...
- [poj1113][Wall] (水平序+graham算法 求凸包)
Description Once upon a time there was a greedy King who ordered his chief Architect to build a wall ...
- (模板)graham扫描法、andrew算法求凸包
凸包算法讲解:Click Here 题目链接:https://vjudge.net/problem/POJ-1113 题意:简化下题意即求凸包的周长+2×PI×r. 思路:用graham求凸包,模板是 ...
- 【BZOJ-1670】Building the Moat护城河的挖掘 Graham扫描法 + 凸包
1670: [Usaco2006 Oct]Building the Moat护城河的挖掘 Time Limit: 3 Sec Memory Limit: 64 MBSubmit: 464 Solv ...
随机推荐
- HTML页面右键事件
<script type="text/javascript"> <!-- document.onmousedown = function (e) { var e ...
- Linq语法学习_增删篇。
关键词: select from where in into join on equals orderby descending thenby Table<TEntity> Default ...
- MovieReview—A dog's purpose(一只狗的使命)
Be Here Now A dog in the movie was reinc ...
- 学习Unity 4.6新GUI系统
(搬运自我在SegmentFault的博客) 最近在学习Unity的过程中,自己做一款小游戏自娱自乐.自然需要用到GUI.但4.5中的GUI很难用,一个选择是传说中的NGUI插件.但对于4.6中的新G ...
- fork新建进程
#include <sys/types.h>#include<sys/wait.h>#include<unistd.h>#include<stdio.h> ...
- CPP-网络/通信:gsoap 的教程和使用
1.1.1 gSOAP 1.1.1 .1 简介 gSOAP 编译工具提供了一个 SOAP/XML 关于 C/C++ 语言的实现,从而让 C/C++ 语言研发 web 服务或客户端程式 ...
- dht 分布式hash 一致性hash区别
先有一致性hash :一致性哈希,似乎最早提出是在分布式缓存里面的,让节点震荡的时候,影响最小.不过现在已经应用在分布式存储和p2p系统里面. dht 是p2p领域的概念,内有三大概念是由keyspa ...
- 【转】vxworks的default boot line说明
boot程序的主要功能是引导vxworks 内核,所以boot程序需要知道vxworks的内核存放在何处,通过什么手段去获取.在vxworks缺省的boot程序里有一条内建的default boot ...
- 【STL学习笔记】一、STL体系
目录 1.标准库以header files形式呈现 2.namespce命名空间 3.STL与OO 4.STL六组件及其关系 5.STL组件例子 6.range-based for statement ...
- NOIP模拟赛 czy的后宫6
czy的后宫6 题目描述 众所周知的是丧尸czy有很多妹子(虽然很多但是质量不容乐观QAQ),今天czy把n个妹子排成一行来检阅.但是czy的妹子的质量实在……所以czy看不下去了.检阅了第i个妹子会 ...