当前位置: 首页 > news >正文

二维凸包——Andrew 算法学习笔记

例题:洛谷P2742【模板】二维凸包

更适合初学者体质的题解。

1.凸包介绍

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

根据三角不等式,凸包也一定是包含所有给定点的周长最小多边形

同样可以理解为,我们在地上钉了一些钉子,有一个有弹性皮筋,我们把它拉大框住所有钉子,然后松手,皮筋的形状就是凸包。

上凸壳(qiao or ke?)一般指凸包的上半部分,看完本篇题解应该会有更深刻的理解。

显然,这个题目求的是凸包的周长。

2.Andrew 算法介绍

一个求凸包的算法,或许也叫安德鲁算法?

我们先按照横坐标为第一关键字,纵坐标为第二关键字,从小到大排序。显然,第一个点和最后一个点一定在凸包上。

我们先考虑求上凸壳,下凸壳同理。

在排好序的点中从小到大枚举,加入一个新点 ccc 时,如果形成了凹多边形(如下图),那么不合法,依照三角不等式,连接点 aaa 和点 ccc 更优,我们直接删掉点 bbb,连接点 aaa 和点 ccc。否则直接加入点 ccc,连接点 bbb 和点 ccc


这样就可以求出上凸壳了。

实现过程其实就是单调栈。

其实按照双关键字排序的作用只有求出第一个和最后一个点,在后续算法中,只需要按照横坐标排序即可。同样,我们发现,除了最后一个点之外,其余相同横坐标的情况下,只有纵坐标最高的点有可能成为上凸壳上的点。当然,这里直接用排序好的数组即可,方便,并且相同横坐标下纵坐标低的也不会影响结果。

如何判断是否形成凹多边形?可以发现,直线 ababab 的斜率小于直线 bcbcbc 的斜率,据此判断即可。如果求斜率有精度问题,可以去分母求(详见代码)。

这样,我们就得到了上凸壳的一个性质:其斜率依次递减。

时间复杂度 $O(n\log_{2}{n}) $,瓶颈在于排序。

3.代码

#include<bits/stdc++.h>
//#define printf __mingw_printf
//在一些本地编译器(如DEV和小熊猫)中,long double有兼容性问题,需要用
//__mingw_printf输出,不过洛谷不需要,而且用__mingw_printf会报错
using namespace std;
const int N=1e5+5;
struct point
{double x,y;
}a[N],q[N];
int n,tp;
bool cmp(point a,point b)
{return a.x==b.x?a.y<b.y:a.x<b.x;
}
int main()
{scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%lf%lf",&a[i].x,&a[i].y);sort(a+1,a+1+n,cmp);q[++tp]=a[1];for(int i=2;i<=n;i++)//求上凸壳{while(tp>=2&&(a[i].y-q[tp].y)*(q[tp].x-q[tp-1].x)>=(q[tp].y-q[tp-1].y)*(a[i].x-q[tp].x))tp--;q[++tp]=a[i];}long double ans=0;//以防万一爆掉for(int i=1;i<tp;i++)//计算凸包周长ans+=sqrt((q[i].y-q[i+1].y)*(q[i].y-q[i+1].y)+(q[i].x-q[i+1].x)*(q[i].x-q[i+1].x));tp=1,q[tp]=a[n];for(int i=n-1;i>=1;i--){while(tp>=2&&(a[i].y-q[tp].y)*(q[tp].x-q[tp-1].x)>=(q[tp].y-q[tp-1].y)*(a[i].x-q[tp].x))tp--;q[++tp]=a[i];}	for(int i=1;i<tp;i++)ans+=sqrt((q[i].y-q[i+1].y)*(q[i].y-q[i+1].y)+(q[i].x-q[i+1].x)*(q[i].x-q[i+1].x));printf("%.2Lf",ans);	//用Lf输出return 0;
}

4.扩展用途

有什么用呢?有没有发现凸包和斜率优化很像?当然还有更多用途,这里就不多说了。

http://www.dtcms.com/a/427703.html

相关文章:

  • 北京网站建设小程序开发360网站建设的目标是什么
  • 河南省建筑市场一体化平台整站优化系统
  • A模块 系统与网络安全 第四门课 弹性交换网络-3
  • 企业电子商务网站平台建设公司概况简介
  • WSL安装并配置到pyCharm
  • 国庆假期小知识:旗帜为何会迎风飘扬
  • 冀教版三年级上册英语-学习思路和引导方法
  • Cesium 内置变量 czm_ellipsoidInverseRadii
  • 做塑胶网站需要什么建设部网站被黑
  • 树莓派:微雪显示器7寸触摸屏使用
  • Spring AI alibaba Prompt模板Advisor自定义
  • 深圳龙华企业网站设计微信推广小程序怎么做
  • 什么是SEM?深入解析其核心优势
  • 主动学习和数据蒸馏在整个多模态大模型流程中的定位与价值
  • 计算机网路-OSPF协议
  • 使用网站效果网站建设用户体验
  • 【Rust GUI开发入门】编写一个本地音乐播放器(12. 国际化应用-多语言支持)
  • 温州企业网站设计制作一个网站多少钱啊
  • 网站开发卖东西网上找工程平台有哪些
  • 单细胞转录组:差异基因分析和富集分析
  • 长沙会议网站设计哪家专业wordpress如何使用主题
  • Javascript数组介绍?什么是数组以及数组的基本使用?
  • 2024年全国大学生信息安全竞赛安徽省赛网络系统建设与运维赛项-网络构建真题
  • 《道德经》第十章
  • 什么网站可以做兼职美工龙海网站开发
  • [学习笔记]对Exsi中的CentOS扩充磁盘空间
  • Linux网络--4、应用层协议Http
  • BIG-Bench:大规模语言模型能力的全面评估与挑战
  • h5网站制作介绍菠菜网站模板
  • 网站建设招聘简介ps建模教程