首页 > 其他分享 >凸包相关

凸包相关

时间:2023-05-27 11:12:25浏览次数:53  
标签:int top DB stk sb 相关 凸包

凸包

二维凸包

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

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

可以以下面的例子来形象理解一下。

下面是一堆木桩,农夫约翰想要围成一个围栏,需要保证所有的木桩都在围栏内,但是约翰想尽量用少的花费。

image

显然我们围着最外面的木桩围起来是最优的

image

所以我们可以这么理解凸包:平面凸包是指覆盖平面上 \(n\) 个点的最小的凸多边形。

那我们怎么让程序围起最外面的木桩呢?

Graham 算法

本质:

Graham 扫描算法维护一个凸壳,通过不断在凸壳中加入新的点和去除影响凸性的点,最后形成凸包。

凸壳就是凸包的一部分。

排序

我们的 Graham 算法的第一步就是对点集进行排序,这样能保证其有序性,从而在后续的处理中更高效。

我们首先先择一个 \(y\) 值最小(如有相同选 \(x\) 最小)的点,记为 \(p_{1}\)。

剩下点集中按照极角的大小逆时针排序,然后编号为 \(p_{2}-p_{m}\)

image

我们按照排序结束时的顺序枚举每一个点,依次连线,这里可以使用一个栈来存储,每次入栈,如果即将入栈的元素与栈顶两个元素所构成了一个类似于凹壳的东西,那么显然处于顶点的那个点一定不在这个点集的凸包上,而他正好在栈顶,所以把它弹出栈,新点入栈。

但是,新来的点有可能既踢走了栈顶,再连接新的栈顶元素后却发现仍然可以踢出,此时就不能忘记判断。

总的时间复杂度为 \(O(n\log n)\)

Andrew 算法

  1. 对所有点进行排序,以 \(x\) 为第一关键字,以 \(y\) 为第二关键字。第 \(1,n\) 两个点一定在凸包上。

  2. 先顺序枚举所有点,求下凸包。用栈来维护当前在凸包上的点;新点入栈前,总要判断该弹出哪些旧点。只要新点处在由栈顶两点构成的有向直线的右侧或共线,就弹出旧点。不能再弹出的时候,新点入栈。

  3. 逆序枚举所有点,求上凸包,用栈维护,和上面一样。

总时间复杂度为 \(O(n\log n)\)。

其实共线的点是不用删的,但是后面计算距离的时候枚举会变多,虽然差不了多少

code:

#include<bits/stdc++.h>
#define int long long
#define DB double
#define N 1000100
using namespace std;
int n,top;
struct sb{DB x,y;}e[N],stk[N];
inline DB cross(sb a,sb b,sb c){return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);}
inline DB js(sb a,sb b){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}
inline int cmp(sb a,sb b){if(a.x==b.x)return a.y<b.y;return a.x<b.x;}
inline DB Andrew()
{
	sort(e+1,e+n+1,cmp);
	for(int i=1;i<=n;i++)
	{
		while(top>1&&cross(stk[top-1],stk[top],e[i])<=0)top--;
		stk[++top]=e[i];
	}
	int t=top;
	for(int i=n-1;i>=1;i--)
	{
		while(top>t&&cross(stk[top-1],stk[top],e[i])<=0)top--;
		stk[++top]=e[i];
	}
	DB res=0;
	for(int i=1;i<top;i++)res+=js(stk[i],stk[i+1]);
	return res;
}
signed main()
{
	cin>>n;
	for(int i=1;i<=n;i++)cin>>e[i].x>>e[i].y;
	DB ans=Andrew();
	printf("%.2lf\n",ans);
	return 0;
}

Convex Hull

这道题目也是一道模板,我们看到里面给了你哪些点是凸包的点,其实可以不用给,因为我们后面能求出来。

我们在算法上选择 Andrew 算法,因为最后要求点从 \(x\) 最小的点开始逆时针输出,这不刚好是我们算法的入栈顺序吗。

这里就体现了手写栈的好处。

#include<bits/stdc++.h>
#define int long long
#define DB double
#define N 1000100
using namespace std;
int t,n,top;char c;
struct sb{DB x,y;}e[N],stk[N];
inline DB cross(sb a,sb b,sb c){return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);}
inline DB js(sb a,sb b){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}
inline int cmp(sb a,sb b){if(a.x==b.x)return a.y<b.y;return a.x<b.x;}
inline void Andrew()
{
	sort(e+1,e+n+1,cmp);
	for(int i=1;i<=n;i++)
	{
		while(top>1&&cross(stk[top-1],stk[top],e[i])<0)top--;
		stk[++top]=e[i];
	}
	int t=top;
	for(int i=n-1;i>=1;i--)
	{
		while(top>t&&cross(stk[top-1],stk[top],e[i])<0)top--;
		stk[++top]=e[i];
	}
}
signed main()
{
	cin>>t;
	while(t--)
	{
		top=0;
		cin>>n;
		for(int i=1;i<=n;i++)cin>>e[i].x>>e[i].y>>c;
		Andrew();
		cout<<top-1<<endl;
		for(int i=1;i<top;i++)cout<<(int)stk[i].x<<" "<<(int)stk[i].y<<endl;
	}
	return 0;
}

参考自:https://www.luogu.com.cn/blog/ShineEternal/convex-hull

标签:int,top,DB,stk,sb,相关,凸包
From: https://www.cnblogs.com/Multitree/p/17436350.html

相关文章

  • LDAPserver相关配置
    [root@schedulershell]#catldapserver.sh#!/bin/bash##LdapServerinstallScript#author:liulingfeng#2023-04-29#--------------------------------------------#1、关闭防火墙sed-i'/SELINUX/s/enforcing/disabled/'/etc/selinux/configsystemctl......
  • 初等数论(Ⅲ):高次同余、阶和原根相关
    前言关于高次同余方程,有\(a^x\equivb(\text{mod}\p)\)和\(x^a\equivb(\text{mod}\p)\)两种类型,后者计算起来较为麻烦,下文就分别记述这两种高次同余方程。离散对数问题离散对数问题是在模\(p\)意义下求解\(\log_ab\),这等价于形如\[a^x\equivb(\text{mod}\p)......
  • 什么是spring以及相关
    参考:https://www.bilibili.com/video/BV1jc411j7u5/?spm_id_from=333.788.recommend_more_video.0&vd_source=46d50b5d646b50dcb2a208d3946b1598......
  • 图的相关知识
    图与之前学习的数据结构不同的地方在于他更加注重数据与数据之间的关系,他又顶点和边构成.图的最经常应用应该是人与人的好感度社交关系的应用.每个人是一个定点,每条边是人与人之间的亲密度.图分为有向图和无向图,无向图是相互之间的关系,有向图是单方面之间的关系.完全图指图中......
  • Windows驱动开发学习记录-使用Inf安装过滤驱动时自动添加注册表相关内容
     做过滤驱动时一般需要在相关class驱动里添加过滤信息,即LowerFilters或者UpperFilters,比如disk类的注册表当前信息,如下图:一个常规的inf文件如下所示:;;USBFilter.inf;[Version]Signature="$WINDOWSNT$"Class=TOASTERClassGuid={B85B7C50-6A01-11d2-B841-00C04FAD517......
  • 数据可视化:相关类可视化图表大全
    大数据时代,工作中我们可能经常会需要处理很多数据,需要在总结汇报中展示呈现,俗话说“字不如表,表不如图”,那么如何缩短数据与用户的距离?让用户一眼Get到重点?在理解或分析大量数据时,数据可视化起着至关重要的作用。数据可视化能使数据“说话”,更容易识别其中的隐藏信息和趋势。因此,......
  • 数据可视化:相关类可视化图表大全
    大数据时代,工作中我们可能经常会需要处理很多数据,需要在总结汇报中展示呈现,俗话说“字不如表,表不如图”,那么如何缩短数据与用户的距离?让用户一眼Get到重点? 在理解或分析大量数据时,数据可视化起着至关重要的作用。数据可视化能使数据“说话”,更容易识别其中的隐藏信息和趋势。......
  • 自动机相关
    前言以下内容大多摘抄自OI-Wiki以及\(\text{Alex\_Wei}\)----自动机相关还有我董晓大爹。确定有限状态自动机(DFA)形式化定义一个确定有限状态自动机(DFA)由以下五部分组成:1.字符集(\(\Sigma\)),该自动机只能输入这些字符2.状态集合(\(Q\)),如果把一个\(DF......
  • 01、虚拟机相关
     四、虚拟机快照通过拍摄虚拟机快照,可以完全克隆一份相同的已配置好的虚拟机,方便以后使用,免除重复创建系统的麻烦;虚拟机快照会存在IP冲突的情况;步骤1、关机--拍摄快照2、克隆主机3、IP冲突解决--改IP地址改最后一位3-254之间的任一数字   #查看网卡名......
  • MySQL快速安装配置及相关命令
    安装下载https://dev.mysql.com/downloads/mysql/配置,解压并建立初始化配置文件my.ini,内容如下:[mysqld]#设置3306端口port=3306#设置mysql的安装目录basedir=D:\mysql-8.0.32-winx64#设置mysql数据库的数据的存放目录datadir=D:\mysql-8.0.32-winx64\data#允......