【题解】「UVA11626」Convex Hull
凸包模板题。
之前写过拿 Graham 算法求凸包的,为了不重复/多学点知识,那这次拿 Andrew 算法求凸包吧qaq
*此文章所有图片均为作者手画。
Andrew 算法
假设我们有这些点:

首先把所有点以横坐标为第一关键字,纵坐标为第二关键字排序。

相对于 Graham 算法来说,Andrew 算法排序更简单,按 \(x, y\) 坐标排序,时间复杂度也更低(一般的坐标系中排序方法)。
首先将 \(p_1\) 入栈。
然后也将 \(p_2\) 入栈,\(p_2\) 可能在,也可能不在,等着之后判断。

随后,发现 \(p_3\) 偏右,所以我们将 \(p_2\) 出栈。

发现 \(p_4\) 依然偏右,\(p_3\) 出栈,\(p_4\) 入栈。

\(p_5\) 向右,\(p_4\) 出栈,\(p_5\) 入栈。

\(p_6\) 向左,入栈。

\(p_7\) 向右,\(p_6\) 出栈,\(p_7\) 入栈。

\(p_8\) 向右,\(p_7\) 出栈,继续检查发现相对于 \(p_5\) \(p_8\) 仍然向右,\(p_5\) 出栈,\(p_8\) 入栈。

此时,我们发现,凸包明明还空一半就到头了???
然而这是意料之中,我们这种算法必然会只算出一半的凸包。
所以我们需要再从排序末尾的点(也就是 \(p_8\))出发,按照一模一样的方式再算一遍就行了。
当然如果我们走过的点就不许要再走了(除了 \(p_1\))
从 \(p_8\) 到 \(p_7\),向左,\(p_7\) 入栈。

\(p_6\) 向右,\(p_7\) 出栈,\(p_6\) 入栈。

\(p_5\) 向左,入栈。

\(p_4\) 向左,入栈。

\(p_3\) 向右,\(p_4\) 出栈,对于 \(p_5\) \(p_3\) 依然向右,\(p_5\) 出栈,\(p_3\) 入栈。

\(p_2\) 向右,\(p_3\) 出栈,\(p_2\) 入栈。

最后将 \(p_2\) 和 \(p_1\) 连起来。

至此,我们的 Andrew 算法就完成了!
扫描的时间复杂度:\(O(n)\)(已过滤常数)
排序时间复杂度:\(O(n \log n)\)
总时间复杂度:\(O(n \log n)\)
Code
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#define line cout << endl
using namespace std;
const int NR = 1e5 + 5;
const double eps = 1e-7;
int n;
struct point {
double x, y;
point () {}
point (double a, double b) : x (a), y (b) {}
bool operator < (const point &b) const {
if (x < b.x) return 1;
if (x > b.x) return 0;
return y < b.y;
}
point operator - (const point &b) {
return point (x - b.x, y - b.y);
}
};
point p[NR], sp[NR];
int cmp (double x) {
if (fabs (x) < eps) return 0;
return x > 0 ? 1 : -1;
}
double dis (point a, point b) {
return sqrt ((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
double cp (point a, point b) {
return a.x * b.y - a.y * b.x;
}
int Andrew () {
sort (p + 1, p + 1 + n);
int len = 0;
for (int i = 1; i <= n; i++) {
while (len > 1 && cmp (cp (sp[len] - sp[len - 1], p[i] - sp[len - 1])) < 0)
len--;
sp[++len] = p[i];
}
int k = len;
for (int i = n - 1; i >= 1; i--) {
while (len > k && cmp (cp (sp[len] - sp[len - 1], p[i] - sp[len - 1])) < 0)
len--;
sp[++len] = p[i];
}
return len;
}
int main () {
int t;
cin >> t;
while (t--) {
cin >> n;
char c;
for (int i = 1; i <= n; i++)
cin >> p[i].x >> p[i].y >> c;
int t = Andrew();
cout << t - 1 << endl;
for (int i = 1; i < t; i++)
printf ("%.0lf %.0lf\n", sp[i].x, sp[i].y);
}
return 0;
}
谢谢qaq
【题解】「UVA11626」Convex Hull的更多相关文章
- 【题解】「UVA681」Convex Hull Finding
更改了一下程序的错误. Translation 找出凸包,然后逆时针输出每个点,测试数据中没有相邻的边是共线的.多测. Solution 首先推销一下作者的笔记 由此进入>>> ( ...
- 【题解】「MCOI-02」Convex Hull 凸包
题目戳我 \(\text{Solution:}\) \[\sum_{i=1}^n \sum_{j=1}^n \rho(i)\rho(j)\rho(\gcd(i,j)) \] \[=\sum_{d=1} ...
- P6810 「MCOI-02」Convex Hull 凸包
Link 一句话题意: 求出 \(\displaystyle\sum_{i=1}^{n}\sum_{j=1}^{m}\tau(i)\tau(j)\tau(gcd(i,j))\) 前置知识 \(diri ...
- 题解 「HDU6403」卡片游戏
link Description 桌面上摊开着一些卡牌,这是她平时很爱玩的一个游戏.如今卡牌还在,她却不在我身边.不知不觉,我翻开了卡牌,回忆起了当时一起玩卡牌的那段时间. 每张卡牌的正面与反面都各有 ...
- 题解 「SCOI2016」萌萌哒
link Description 一个长度为 $ n $ 的大数,用 $ S_1S_2S_3 \ldots S_n $表示,其中 $ S_i $ 表示数的第 $ i $ 位,$ S_1 $ 是数的最高 ...
- 题解 「SDOI2017」硬币游戏
题目传送门 Description 周末同学们非常无聊,有人提议,咱们扔硬币玩吧,谁扔的硬币正面次数多谁胜利. 大家纷纷觉得这个游戏非常符合同学们的特色,但只是扔硬币实在是太单调了. 同学们觉得要加强 ...
- 题解 「ZJOI2018」历史
题目传送门 Description 九条可怜是一个热爱阅读的女孩子. 这段时间,她看了一本非常有趣的小说,这本小说的架空世界引起了她的兴趣. 这个世界有 \(n\) 个城市,这 \(n\) 个城市被恰 ...
- 题解 「BZOJ3636」教义问答手册
题目传送门 Description 作为泉岭精神的缔造者.信奉者.捍卫者.传承者,Pear决定印制一些教义问答手册,以满足泉岭精神日益增多的信徒.Pear收集了一些有关的诗选.语录,其中部分内容摘录在 ...
- 题解「BZOJ4310」跳蚤
题目传送门 Description 现在有一个长度为 \(n\) 的字符串,将其划分为 \(k\) 段,使得这 \(k\) 段每一段的字典序最大子串中字典序最大的字符串字典序尽量小.求出这个字符串. ...
随机推荐
- 主动关闭 time-wait 2msl 处理
先上传后面整理 /* * This routine is called by the ICMP module when it gets some * sort of error condition. ...
- history命令的优化
前言 默认的history记录的信息有限,我们对这个进行一定的扩充 我们看下大概哪几个需求 记录用户登陆的ip 记录用户的名称 记录执行命令的时间 具体实现 我们看下应该怎么做这个,尽量在不改变用户的 ...
- MYSQL学习(三) --索引详解
创建高性能索引 (一)索引简介 索引的定义 索引,在数据结构的查找那部分知识中有专门的定义.就是把关键字和它对应的记录关联起来的过程.索引由若干个索引项组成.每个索引项至少包含两部分内容.关键字和关键 ...
- MathType在AutoCAD中的应用方法
我们都知道CAD是一款鼎鼎有名设计与绘图软件,有不少朋友可能用过或听说过CAD,相较而言,用过MathType的人可能要少一些,虽然它也是理科生与工科生的专用工具之一. 通过MathType我们能够在 ...
- 【Python】python 入门与进阶
github地址:https://github.com/wangxiao9/basic_python.git
- 设置searchDisplayController的searchResultsTableView的UITableViewStyle为grouped
[self.searchDisplayController setValue:[NSNumber numberWithInt:UITableViewStyleGrouped] forKey:@&quo ...
- python接口测试3-JSON格式
什么是JSON? 一种轻量级的数据交换格式.它独立于语言和平台,JSON解析器和JSON库支持不同的编程语言.JSON具有自我描述性,很容易理解. 数据格式: { "name":& ...
- python搭建本地共享文件服务器
1.安装python 去官网下载python最新版,然后安装配置好环境 2.运行命令 在终端上输入以下命令 python3 -m http.server 当你执行完这个命令的时候,你的电脑会监听 80 ...
- 【电子取证:FTK Imager篇】DD、E01系统镜像仿真
星河滚烫,人生有理想! ---[suy999] DD.E01系统镜像动态仿真 (一)使用到的软件 1.FTK Imager (v4.5.0.3) 2.VMware Workstation 15 P ...
- Java基础教程——使用Eclipse快速编写Java输入输出代码
Eclipse安装 IDE:Integrated Development Environment,集成开发环境.好比是全自动洗衣机. 此处使用[eclipse-jee-4.6-neon-3-win32 ...