水平序 Graham 扫描算法:

计算二维凸包的时候可以用到,Graham 扫描算法有水平序和极角序两种。

极角序算法能一次确定整个凸包,

但是计算极角需要用到三角函数,速度较慢,精度较差,特殊情况较多。

水平序算法需要扫描两次,但排序简单,讨论简单,不易出错。

【算法流程】

1.对顶点按x为第一关键字,y为第二关键字进行排序。

2.准备一个空栈,并将前两个点压入栈。

3.对于每一个顶点A,只要栈顶中还至少两个顶点,记栈顶为T,栈中第二个为U。

若UT(向量) * TA(向量) <= 0, 则将T弹出。重复此过程。

4.直到上一步不再弹出顶点,将A压入栈。扫描完一遍之后得到凸包的下凸壳

5.将点集倒过来再进行一次,得到凸包的上凸壳,组合起来即可。

【算法的时间复杂度】

算法的瓶颈在排序,所以时间复杂度是 O(N log N)。 若坐标均为整数,可以用基数排序将复杂度优化到 O(N)。

贴上代码了~:

//#pragma comment(linker, "/STACK:16777216") //for c++ Compiler
#include <stdio.h>
#include <iostream>
#include <cstring>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <algorithm>
#define ll long long
#define Max(a,b) (((a) > (b)) ? (a) : (b))
#define Min(a,b) (((a) < (b)) ? (a) : (b))
#define Abs(x) (((x) > 0) ? (x) : (-(x)))
using namespace std; const int INF = 0x3f3f3f3f;
const int MAXN = ;
const double eps = 1e-; struct POINT{
int x;
int y;
POINT() : x(), y() {};
POINT(double _x_, double _y_) : x(_x_), y(_y_) {};
}; bool operator < (const POINT & l, const POINT & r){
return l.y < r. y || (l.y == r.y && l.x < r.x);
} int Cross(const POINT & a, const POINT & b, const POINT & o){
return (a.x - o.x) * (b.y - o.y) - (b.x - o.x) * (a.y - o.y);
} int SquareDis(POINT a, POINT b){
return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
} int Graham(POINT *pnt, POINT *res, int n){
int i, len, top =;
sort(pnt, pnt + n);
if (n == )
return ;
res[] = pnt[];
if (n == )
return ;
res[] = pnt[];
if (n == )
return ;
res[] = pnt[];
for (i =; i < n; i++){
while (top && Cross(pnt[i], res[top], res[top -]) >= )
top--;
res[++top] = pnt[i];
}
len = top;
res[++top] = pnt[n -];
for (i = n -; i >=; i--){
while (top != len && Cross(pnt[i], res[top], res[top -]) >= )
top--;
res[++top] = pnt[i];
}
return top;
} int rotating_calipers(POINT *ch, int n){
int q =, ans =;
ch[n] = ch[];
for (int i = ; i < n; ++i){
while (Cross(ch[i + ], ch[q + ], ch[i]) > Cross(ch[i + ], ch[q], ch[i]))
q = (q +) % n;
ans = max(ans, max(SquareDis(ch[i], ch[q]), SquareDis(ch[i + ], ch[q + ])));
}
return ans;
} int main(){
POINT pnt[MAXN], res[MAXN];
int n;
while(EOF != scanf("%d",&n)){
for (int i = ; i < n; i++)
scanf("%d%d", &pnt[i].x, &pnt[i].y);
int count = Graham(pnt, res, n);
int ans = rotating_calipers(res, count);
printf("%d\n", ans);
}
return ;
}

POJ 2187 旋转卡壳 + 水平序 Graham 扫描算法 + 运算符重载的更多相关文章

  1. Poj 2187 旋转卡壳

    Poj 2187 旋转卡壳求解 传送门 旋转卡壳,是利用凸包性质来求解凸包最长点对的线性算法,我们逐渐改变每一次方向,然后枚举出这个方向上的踵点对(最远点对),类似于用游标卡尺卡着凸包旋转一周,答案就 ...

  2. 二维凸包 Graham扫描算法

    题目链接: http://poj.org/problem?id=1113 求下列点的凸包 求得凸包如下: Graham扫描算法: 找出最左下的点,设为一号点,将其它点对一号点连线,按照与x轴的夹角大小 ...

  3. poj 2079(旋转卡壳求解凸包内最大三角形面积)

    Triangle Time Limit: 3000MS   Memory Limit: 30000K Total Submissions: 9060   Accepted: 2698 Descript ...

  4. [poj1113][Wall] (水平序+graham算法 求凸包)

    Description Once upon a time there was a greedy King who ordered his chief Architect to build a wall ...

  5. poj 3608(旋转卡壳求解两凸包之间的最短距离)

    Bridge Across Islands Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9768   Accepted: ...

  6. Bridge Across Islands POJ - 3608 旋转卡壳求凸包最近距离

    \(\color{#0066ff}{题目描述}\) 几千年前,有一个小王国位于太平洋的中部.王国的领土由两个分离的岛屿组成.由于洋流的冲击,两个岛屿的形状都变成了凸多边形.王国的国王想建立一座桥来连接 ...

  7. POJ 3608 旋转卡壳

    思路: 旋转卡壳应用 注意点&边  边&边  点&点 三种情况 //By SiriusRen #include <cmath> #include <cstdi ...

  8. poj 3608 旋转卡壳求不相交凸包最近距离;

    题目链接:http://poj.org/problem?id=3608 #include<cstdio> #include<cstring> #include<cmath ...

  9. POJ C++程序设计 编程题#3 编程作业—运算符重载

    编程题 #3 来源: POJ (Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩.) 注意: 总时间限制: 1000ms 内存限制: 65536kB 描述 写一个二维数组 ...

随机推荐

  1. cocos2d-x spine 加载粒子特效

    spine骨骼加载粒子效果 将粒子效果加到骨骼上,update位置和角度.h#ifndef __HOMESCENE_H__#define __HOMESCENE_H__#include "c ...

  2. 前端笔试题 JS部分

    题目 http://www.itmian4.com/forum.php?mod=viewthread&tid=4540 http://www.itmian4.com/forum.php?mod ...

  3. USB3.0 和usb 2.0的区别

    USB3.0拥有10倍于USB2.0的速度,可惜DIY“江湖”险恶,如果咱们不掌握如何识别USB3.0的方法,很容易被JS忽悠.何况,USB3.0主板不等于USB3.0机箱,很多朋友在选购时都忽略了一 ...

  4. 射频识别技术漫谈(25)——Felica简介

    Felica是SONY公司开发的射频识别技术,该技术使用的载波频率与ISO14443A和ISO14443B一样,都是13.56MHz,所以有人把它称为ISO14443C,但SONY并没有正式接受这样的 ...

  5. Cocos2d—X游戏开发之VS2010 控制台输出中文,模拟器中文乱码问题解决

    首先,先解决第一个问题,我们使用VS2010开发的时候,调试的时候,中文打印出来都是乱码,这个问题很纠结. 如下图: CCLOG("cclog: 测试使用标签的自动换行和个别字体大写&quo ...

  6. HDU 1130 How Many Trees?

    裸的卡特兰数 C++#include<iostream> #include<cstdio> using namespace std; #define base 10000 #d ...

  7. Qt WebKit and HTML5 geolocation | Qt Project forums | Qt Project

    Qt WebKit and HTML5 geolocation | Qt Project forums | Qt Project Qt WebKit and HTML5 geolocation   I ...

  8. [dfs+水] hdu 4462 Scaring the Birds

    题意: N*N的矩阵中有M个点能够放稻草人.且给覆盖距离R 每一个稻草人能覆曼哈顿距离R以内的点 问最少须要多少个稻草人 思路: 由于范围非常小,直接能够暴力 注意稻草人所在的位置是不须要被覆盖的 代 ...

  9. java项目组会议纪要

    上周五项目经理开例会让我记录会议纪要,以下是我记录的纪要.给大家分享一下! 一.时间:2014年04月25日 二.地点:研发部 三.人物:xx,xx,xx 四.内容(相关项目的一些事项): 1.对待需 ...

  10. Node.js入门-Node.js 介绍

    Node.js 是什么 Node.js 不是一种独立的语言,与 PHP,Python 等"既是语言优势平台"不同,它也不是一个 JavaScrip 框架,不同于 CakePHP,D ...