POJ 2187 旋转卡壳 + 水平序 Graham 扫描算法 + 运算符重载
水平序 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 扫描算法 + 运算符重载的更多相关文章
- Poj 2187 旋转卡壳
Poj 2187 旋转卡壳求解 传送门 旋转卡壳,是利用凸包性质来求解凸包最长点对的线性算法,我们逐渐改变每一次方向,然后枚举出这个方向上的踵点对(最远点对),类似于用游标卡尺卡着凸包旋转一周,答案就 ...
- 二维凸包 Graham扫描算法
题目链接: http://poj.org/problem?id=1113 求下列点的凸包 求得凸包如下: Graham扫描算法: 找出最左下的点,设为一号点,将其它点对一号点连线,按照与x轴的夹角大小 ...
- poj 2079(旋转卡壳求解凸包内最大三角形面积)
Triangle Time Limit: 3000MS Memory Limit: 30000K Total Submissions: 9060 Accepted: 2698 Descript ...
- [poj1113][Wall] (水平序+graham算法 求凸包)
Description Once upon a time there was a greedy King who ordered his chief Architect to build a wall ...
- poj 3608(旋转卡壳求解两凸包之间的最短距离)
Bridge Across Islands Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9768 Accepted: ...
- Bridge Across Islands POJ - 3608 旋转卡壳求凸包最近距离
\(\color{#0066ff}{题目描述}\) 几千年前,有一个小王国位于太平洋的中部.王国的领土由两个分离的岛屿组成.由于洋流的冲击,两个岛屿的形状都变成了凸多边形.王国的国王想建立一座桥来连接 ...
- POJ 3608 旋转卡壳
思路: 旋转卡壳应用 注意点&边 边&边 点&点 三种情况 //By SiriusRen #include <cmath> #include <cstdi ...
- poj 3608 旋转卡壳求不相交凸包最近距离;
题目链接:http://poj.org/problem?id=3608 #include<cstdio> #include<cstring> #include<cmath ...
- POJ C++程序设计 编程题#3 编程作业—运算符重载
编程题 #3 来源: POJ (Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩.) 注意: 总时间限制: 1000ms 内存限制: 65536kB 描述 写一个二维数组 ...
随机推荐
- Move WriteBuffer ReadBuffer String
在实际编程中,经常会用到Buffer,当string作为Buffer传值时需要注意的是 1, string的值的起始索引是1,千万记住! 2, 有时候需要先告诉系统去开辟出内存空间,用SetLengt ...
- 分区 Service Bus 队列和主题
编辑人员注释:本文章由 Windows Azure Service Bus 团队的二级项目经理 Ruppert Koch 撰写. 上周,Microsoft 发布了 Azure SDK 2.2 和 Se ...
- Laravel + Xdebug 时需要注意的问题
[平台环境]64bit Win7 + Wamp2.5 (php 5.5, Apache 2.4.9) [Xdebug版本]php_xdebug-2.2.5-5.5-vc11-x86_64.dll 配置 ...
- Warning: Unable to send packet: Error with PF_PACKET send() [11]: Message too long (errno = 90)
今天在使用tcpreplay重放流量时,发现有的数据包没有发送成功: Warning: Unable to send packet: Error with PF_PACKET send() [215] ...
- C++类成员常量
由于#define 定义的宏常量是全局的,不能达到目的,于是想当然地觉得应该用const 修饰数据成员来实现.const 数据成员的确是存在的,但其含义却不是我们所期望的.const 数据成员只在某个 ...
- Tree(未解决。。。)
Tree Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submi ...
- jQ 操作积累
1.判断radio是否选中:方式一:var val=$('input:radio[name="sex"]:checked').val(); //(val==null 未选中) 方式 ...
- pre标签 首行会自动换行解决方案
利用pre标签可以 解决文本文档里面的空格及换行在页面上不显示的方案, 自行换行 加 white-space: pre-wrap; word-wrap: break-word; 英文字母换行 word ...
- 离线安装.NET 3.5小记
最近为系统新增一个功能,写完以后进行部署,发现在IIS7上部署没有问题,但是IIS6上部署会出现未知情况,具体表现为取不到数据,估计是IIS6和IIS7直接的差异导致程序异常退出. 为了重现异常,在本 ...
- 【Spring】手动获取spring容器对象时,报no qualifying bean of type is defined
手动获取容器对象时,报no qualifying bean of type is defined, 经过调查,发现手动获取的时候,该类所在的包必须经过spring容器初始化. 1.SpringConf ...