凸包模板题。

之前写过拿 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的更多相关文章

  1. 【题解】「UVA681」Convex Hull Finding

    更改了一下程序的错误. Translation 找出凸包,然后逆时针输出每个点,测试数据中没有相邻的边是共线的.多测. Solution 首先推销一下作者的笔记 由此进入>>> ( ...

  2. 【题解】「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} ...

  3. P6810 「MCOI-02」Convex Hull 凸包

    Link 一句话题意: 求出 \(\displaystyle\sum_{i=1}^{n}\sum_{j=1}^{m}\tau(i)\tau(j)\tau(gcd(i,j))\) 前置知识 \(diri ...

  4. 题解 「HDU6403」卡片游戏

    link Description 桌面上摊开着一些卡牌,这是她平时很爱玩的一个游戏.如今卡牌还在,她却不在我身边.不知不觉,我翻开了卡牌,回忆起了当时一起玩卡牌的那段时间. 每张卡牌的正面与反面都各有 ...

  5. 题解 「SCOI2016」萌萌哒

    link Description 一个长度为 $ n $ 的大数,用 $ S_1S_2S_3 \ldots S_n $表示,其中 $ S_i $ 表示数的第 $ i $ 位,$ S_1 $ 是数的最高 ...

  6. 题解 「SDOI2017」硬币游戏

    题目传送门 Description 周末同学们非常无聊,有人提议,咱们扔硬币玩吧,谁扔的硬币正面次数多谁胜利. 大家纷纷觉得这个游戏非常符合同学们的特色,但只是扔硬币实在是太单调了. 同学们觉得要加强 ...

  7. 题解 「ZJOI2018」历史

    题目传送门 Description 九条可怜是一个热爱阅读的女孩子. 这段时间,她看了一本非常有趣的小说,这本小说的架空世界引起了她的兴趣. 这个世界有 \(n\) 个城市,这 \(n\) 个城市被恰 ...

  8. 题解 「BZOJ3636」教义问答手册

    题目传送门 Description 作为泉岭精神的缔造者.信奉者.捍卫者.传承者,Pear决定印制一些教义问答手册,以满足泉岭精神日益增多的信徒.Pear收集了一些有关的诗选.语录,其中部分内容摘录在 ...

  9. 题解「BZOJ4310」跳蚤

    题目传送门 Description 现在有一个长度为 \(n\) 的字符串,将其划分为 \(k\) 段,使得这 \(k\) 段每一段的字典序最大子串中字典序最大的字符串字典序尽量小.求出这个字符串. ...

随机推荐

  1. Hive 报错 Failed to load class "org.slf4j.impl.StaticLoggerBinder".

    打开hive报错 SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: Defaultin ...

  2. 【进阶之路】Mybatis-Plus中乐观锁@version注解的问题与解决方案

    大家好,我是练习java两年半时间的南橘,从一名连java有几种数据结构都不懂超级小白,到现在懂了一点点的进阶小白,学到了不少的东西.知识越分享越值钱,我这段时间总结(包括从别的大佬那边学习,引用)了 ...

  3. 重闯Sqli-labs关卡第三天(11-15关)

    前言 今天早上学了学网易云课堂的注入课程突然感觉网易云可i春秋联合出品的课程还不错,之后就刷了刷攻防世界的题,题有眉目但是还是忍不住看了WP 服了自己了!!!一直刷到了晚上也不知道几点我妈买了柚子回了 ...

  4. 保证看完就会!大数据YRAN核心知识点来袭!

    01 我们一起学大数据 大家好,今天分享的是大数据YRAN的核心知识点,老刘尽量用通俗易懂的话来讲述YARN知识点,争取做到大家看完后能够用口语化的形式将它们表达出来,做到真正的看完就会!(如果觉得老 ...

  5. Mac下载工具folx如何下载常用的软件

    最近,多档综艺节目都开展得如火如荼,比如<中国新说唱>.<这就是街舞>等深受年轻人喜欢的综艺节目.虽然手机端也可观看,但可以的话,当然是使用电脑屏幕观看节目比较过瘾. 接下来, ...

  6. FL studio系列教程(十):FL Studio中如何新建样本

    FL Studio中强调以样本为核心的编曲模式.样本其实就是一个小的音序片段,可以是单独的乐器或单独的打击乐,还可以是他们组合的一个小音序片段,它是我们学习编曲的最基础知识.所以本文主要为大家讲解的是 ...

  7. word选择+快捷键

    统一修改红色章节标题字体:将鼠标放置在章节标题中,前提是各章节标题采用的格式是一样的,单击"选择"-"选择格式相似的文本"即可全部选中进行设置 如下图,章节标题 ...

  8. Linux中的基本命令无法使用,报Command not found的错误的解决方法

    一般我们在Linux中执行命令的时候,会报 Command not found 的错误,报这种错误一般有两种原因:一是你的系统中没有安装这个命令,需要你手动安装,另外一种原因就是平常这些命令用着好好的 ...

  9. 浅谈 van Emde Boas 树——从 u 到 log log u 的蜕变

    本文参考算法导论完成. 模板题在此 QwQ 优化的过程比较长,还请读者耐心阅读,认真理解. 最初的想法 我会暴力! 用一个 \(size\) 数组维护每个元素出现的次数. 不细讲,时间复杂度 \(O( ...

  10. C语言是如何诞生的?地位怎样?未来发展趋势?

      C语言的历史 C语言的原型是A语言(ALGOL 60语言). 1963年,剑桥大学将ALGOL 60语言发展成为CPL(Combined Programming Language)语言. 1967 ...