Andrew 算法求凸包

参考资料:

右手定则(baidu.com)

内积和外积 - OI Wiki (oi-wiki.org)

  • \(a\) 与 \(b\) 相对位置

    • \(b\) 在 \(a\) 的逆时针方向: \(a \times b>0\)
    • 顺负逆正(其实就是高中数学对于正负角的定义)

凸包 - OI Wiki (oi-wiki.org)

  • 伪代码

while(右旋){

标记原来的栈顶为不在凸包上

}

标记新点在栈顶上

加入栈中

  • 一般是叉积小于0则不合法(=0是平的,但合法)

二维凸包

定义

凸多边形

凸多边形是指所有内角大小都在 \([0,\pi]\) 范围内的 简单多边形

凸包

在平面上能包含所有给定点的最小凸多边形叫做凸包。

实际上可以理解为用一个橡皮筋包含住所有给定点的形态。

凸包用最小的周长围住了给定的所有点。如果一个凹多边形围住了所有的点,它的周长一定不是最小,如下图。根据三角不等式,凸多边形在周长上一定是最优的。

Andrew 算法求凸包

过程:

1、首先以 \(x\) 为第一关键字, \(y\) 为第二关键字排序

2、显然排序后最小的元素和最大的元素一定在凸包上。而且因为是凸多边形,我们如果从一个点出发逆时针走,轨迹总是「左拐」的,一旦出现右拐,就说明这一段不在凸包上。因此我们可以用一个单调栈来维护上下凸壳。

因为从左向右看,上下凸壳所旋转的方向不同,为了让单调栈起作用,我们首先 升序枚举 求出下凸壳,然后 降序 求出上凸壳。

  • 左右旋的判定:叉积的正负(左旋为正角,右旋为负角,0证明是平的一段)

二维凸包模板:Luogu P2742 Fencing the Cows

#include<bits/stdc++.h>
#define F(i,l,r) for(int i(l);i<=r;++i)
#define G(i,r,l) for(int i(r);i>=l;--i)
#define double long double
using namespace std;
using ll = long long;
const int N=1e5+105;
struct node{
double x,y;
node operator - (const node &o)const{
node z=(node){x-o.x,y-o.y};
return z;
}
double operator * (const node &o)const{
return x*o.y-y*o.x;
}
bool operator < (const node &o)const{
return x==o.x ? y<o.y : x<o.x;
}
}w[N];
double dis(node a){
return __builtin_sqrt(a.x*a.x+a.y*a.y);
}
int tp=0,n;
int stk[N<<1];
bool used[N];
double ans=0;
signed main(){
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin>>n; F(i,1,n) cin>>w[i].x>>w[i].y;
sort(w+1,w+n+1);
stk[++tp]=1;//used不打标记方便最后封闭
F(i,2,n){
while(tp>=2 && (w[stk[tp]]-w[stk[tp-1]])*(w[i]-w[stk[tp]])<0) used[stk[tp--]]=0;
//注意叉积小于0,一定不能写成小于等于!
used[i]=1;
stk[++tp]=i;
}
G(i,n,1){
if(used[i]) continue;
while(tp>=2 && (w[stk[tp]]-w[stk[tp-1]])*(w[i]-w[stk[tp]])<0) used[stk[tp--]]=0;
used[i]=1;
stk[++tp]=i;
}
F(i,1,tp-1) ans+=dis(w[stk[i+1]]-w[stk[i]]);//凸包周长的求法
ans+=dis(w[stk[1]]-w[stk[tp]]);
cout<<fixed<<setprecision(2)<<ans<<"\n";
return 0;
}

Andrew 算法求凸包的更多相关文章

  1. 图解 Andrew 算法求凸包

    前言 Andrew 算法可以在 \(O(n\log n)\) 的时间复杂度通过单调栈分别求出散点的上凸壳和下凸壳,来求出平面上一些点的凸包. 看懂这篇博客,大家需要掌握: 基础计算几何知识 单调栈 凸 ...

  2. (模板)graham扫描法、andrew算法求凸包

    凸包算法讲解:Click Here 题目链接:https://vjudge.net/problem/POJ-1113 题意:简化下题意即求凸包的周长+2×PI×r. 思路:用graham求凸包,模板是 ...

  3. Andrew算法求二维凸包-学习笔记

    凸包的概念 首先,引入凸包的概念: (有点窄的时候...图片右边可能会被吞,拉开图片看就可以了) 大概长这个样子: 那么,给定一些散点,如何快速地求出凸包呢(用在凸包上的点来表示凸包) Andrew算 ...

  4. LA 4728 旋转卡壳算法求凸包的最大直径

    #include<iostream> #include<cstdio> #include<cmath> #include<vector> #includ ...

  5. nyoj-78-圈水池(Graham算法求凸包)

    题目链接 /* Name:nyoj-78-圈水池 Copyright: Author: Date: 2018/4/27 9:52:48 Description: Graham求凸包 zyj大佬的模板, ...

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

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

  7. POJ 2187 Beauty Contest【旋转卡壳求凸包直径】

    链接: http://poj.org/problem?id=2187 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=22013#probl ...

  8. 旋转卡壳(求凸包直径)学习笔记 | 题解 P1452 [USACO03FALL]Beauty Contest G /【模板】旋转卡壳

    前言 旋转卡壳(Rotating Calipers)可以在凸包上维护许多有用的信息,最常见的就是凸包直径(平面最远点对). 注意:本文不介绍所谓的 "人类智慧" 乱搞做法. 算法流 ...

  9. 计算几何 二维凸包问题 Andrew算法

    凸包:把给定点包围在内部的.面积最小的凸多边形. Andrew算法是Graham算法的变种,速度更快稳定性也更好. 首先把全部点排序.依照第一keywordx第二keywordy从小到大排序,删除反复 ...

  10. Beauty Contest(graham求凸包算法)

    Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 25256   Accepted: 7756 Description Bess ...

随机推荐

  1. SpringBoot复习

    SpringBoot 开启事务:Application 加@EnableTransactionManagement ,Service方法加@Transaction 注解 注意:@Transaction ...

  2. 【全】CSS动画大全之其他【火影忍者动态背景】

    效果预览 代码 <!DOCTYPE html> <html> <head> <head> <meta charset="utf-8&qu ...

  3. 组合逻辑环(Combinational Logic Loop)

    组合逻辑电路 组合逻辑电路是数字电子学中一类基本的电路类型,它由一系列逻辑门组成,用于实现特定的逻辑功能.与时序逻辑电路不同,组合逻辑电路的输出完全取决于当前的输入信号,而不受之前输入的影响.换句话说 ...

  4. 删除链表倒数第N个节点(19)

    双指针法 双指针法主要是最开始有两个指针fast,slow都指向链表的虚拟头节点dummy,然后快指针先移动,这里需要先向后移动n+1位(因为你最终是要找到目标节点的前一个节点),然后slow和fas ...

  5. Python新手爬虫一:爬取影片名称评分等

    豆瓣网站:https://movie.douban.com/chart 先上最后的代码: from bs4 import BeautifulSoup from lxml import html imp ...

  6. jenkins动态切换环境

    一.代码层实现动态切换 1.首先在conftest.py下声明pytest_addoption钩子函数,写法如下 def pytest_addoption(parser): # 设置要接收的命令行参数 ...

  7. jstack排查cpu占用高的步骤

    通过jstack排查cpu占用高的问题 1.通过top命令找到cpu占用高的应用程序进程 2.通过top -H -p pid查看该应用中占用CPU高的线程. 3.通过printf "%x\n ...

  8. CSS & JS Effect – Tooltip

    介绍 Tooltip 长这样 它用 popup 的方式来详细描述一个主体. 比如某个 icon 代表着什么. 参考 YouTube – How To Make Tooltips With Only C ...

  9. MDC – Get Started

    前言 Angular Material 为了更好的和 Material Design 保持一致, 放弃了自己开发, 改而使用 wrapping MDC 的方式来维护 Angular Material. ...

  10. MyBatisPlus——简介

    概述 MyBatisPlus(简称MP)是基于MyBatisPlus框架基础上开发的增强型工具,旨在简化开发.提高效率 国内开发的技术 特性 无侵入:只做增强不做改变,不会对现有工程产生影响 强大的C ...