平面上最近点对

news2024/12/23 14:41:11

 OJ:P1429 平面最近点对(加强版) - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

非常详细的博客:平面上最近点对 - 洛谷专栏 (luogu.com.cn)

更正式的文章:平面最近点对 - OI Wiki

这也是我们算法课的一个实验。不过我做的不好,我只会简单的分治,中间区域合并时用的还是蛮力QAQ。

分治学好后,难点其实在合并这里的处理。(直接想极端情况吧,所有点的x都相同)

————————

图解总思路:

1.分治:

————

2.中间处理部分:

(注意我们是用序号排的序,二分也是根据序号二分)

这个中线可以是“mid点”

理解:

其实极端情况就是存在更近点对且mid离他们很远。注意这两个点的x和y都是很近的,距离小于d,而他们离mid的x也绝对都小于d,所以是在范围内的。

所以这个2d其实可以再缩减,mid向右d 与 mid+1向左d 的交集 ,如果是mid或者mid+1能有更近点对,那么这个d是足够的,再远点x都大于d了。

————

3.中间合并部分

对于每个左边的点比如P,最多检查右边这六个点。

其实最多五个,右边三个距离肯定大于d了。

但如何做到高效比较呢,只能将中间部分左右的所有点排个序,一起比了。

根据y坐标排序,

每个点比后面的点,直到纵坐标之差超过d。

排序O(nlongn) , 比较O(5n)  (这里比较只比自己下面的,左边也可能下面也有一个d,见下图)

合并部分每次总的就是O(nlongn + n)

如果每次都这样的话,总的其实是 O( (nlogn+n) *  logn )

可以进一步优化:

前面排好,直接给后面用。 可能会多循环一些点,但是消耗远比排序小。

(这样做就不是先找点,排序,比较了,而是排序,合法点,比较。注意第一层循环和mid的x距离超了就不用比了,不在范围内)

合并部分每次就是O(n)了

总的合并部分就是O(n*logn)了

————

总的时间复杂度:

排序加上分治的时间复杂度结果为 2nlongn + n ,即 nlongn

参考代码:

其实全程跟mindis比就可以。

#define ll long long
#define endl "\n"
//#define int long long
#define PII pair<int,int>
const int maxn = 100000;

struct Point
{
	int x, y;
};

double mindis = DBL_MAX;

void distance(const Point& a, const Point& b)
{
	mindis = min(mindis,sqrt(pow(a.x - b.x, 2) + pow(a.y - b.y, 2)));
}

vector<Point>arr,arr2,tmp;
pair<Point, Point> closestPair;

void fmerge(int l, int r)
{
	double dis = DBL_MAX;

	if (l == r)
		return;
	else if (l + 1 == r)
	{
		if (arr2[l].y > arr2[r].y)
			swap(arr2[l], arr2[r]);

		return;
	}
	

	int m = l + ((r - l) >> 1);
	fmerge(l, m);
	fmerge(m + 1, r);

	int al = l, bl = m + 1,tot = l;
	while (al <= m && bl <= r)
	{
		if (arr2[al].y < arr2[bl].y)
			tmp[tot++] = arr2[al++];
		else
			tmp[tot++] = arr2[bl++];
	}
	while(al <= m)
		tmp[tot++] = arr2[al++];
	while(bl <= r)
		tmp[tot++] = arr2[bl++];
	for (int i = l; i <= r; i++)
		arr2[i] = tmp[i];


	for (int i = l; i < r; i++)
	{
		//mid
		if(abs(arr2[i].x - arr[m].x)<mindis)
		for (int j = i + 1; j <=r  && tmp[j].y - tmp[i].y <= mindis; j++)
		{
			distance(tmp[i], tmp[j]);
		}
	}

	return;
}

void findTwoPointsWithTheShortestDistance()
{
	int size = arr.size();
	sort(arr.begin(), arr.end(), [&](const Point& a, const Point& b) {
		if (a.x == b.x)
			return a.y < b.y;//return a.y <= b.y;
		return a.x < b.x;
		}
	);
	arr2 = arr;
	tmp = vector<Point>(arr.size());
	fmerge(0, size - 1);
}

void solve()
{
	int n;
	cin >> n;
	arr = vector<Point>(n);
	for (int i = 0; i < n; i++)
	{
		int a, b;
		cin >> a >> b;
		arr[i] = { a,b };
	}

	findTwoPointsWithTheShortestDistance();
	//cout << mindis << endl;
	printf("%.4lf", mindis);
}

signed main()
{

	//ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);

	solve();



	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1595189.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Eigen库从入门到放弃(2. Getting Started)

Eigen的头文件定义了多种类型&#xff0c;但是对于简单的来说&#xff0c;使用MatrixXd就足够了&#xff0c;MatrixXd表示任意尺寸的矩阵&#xff0c;但是要注意数据类型是double的。Eigen/Dense的头文件定义了所有MatrixXd和相关类型的成员函数。所有头文件中定义的函数都是在…

康耐视visionpro-CogFindCircleTool操作工具详细说明

◆CogFindCircleTool]功能说明: 通过用多个卡尺找到多个点来拟合所要找的圆 ◆CogFindCircleTool操作说明: ①.打开工具栏,双击或点击鼠标拖拽添加CogFindCircleTool工具 ②.添加输入图像,右键“链接到”或以连线拖拽的方式选择相应输入源 ③预期的圆弧:设置预期圆弧的…

python-numpy(3)-线性代数

一、方程求解 参考资料 对于Ax b 这种方程&#xff1a; np.linalg.inv(A).dot(B)np.linalg.solve(A,b) 1.1 求解多元一次方程一个直观的例子 # AXB # X A^(-1)*B A np.array([[7, 3, 0, 1], [0, 1, 0, -1], [1, 0, 6, -3], [1, 1, -1, -1]]) B np.array([8, 6, -3, 1]…

Unity上接入手柄,手柄控制游戏物体移动

1、unity软件上安装system input 组件。菜单栏【window】-【Packag Manager】打开如下界面,查找Input System,并且安装。 2、安装成功后插入手柄到windows上,打开菜单栏上【window】--【Analysis】--【Input Debuger】 进入Input Debug界面,可以看到手柄设备能被Unity识别。…

Flutter - iOS 开发者速成篇

首先 安装FLutter开发环境&#xff1a;M1 Flutter SDK的安装和环境配置 然后了解Flutter和Dart 开源电子书&#xff1a;Flutter实战 将第一章初略看一下&#xff0c;你就大概了解一下Flutter和Dart这门语言 开始学习Dart语言 作为有iOS经验的兄弟们&#xff0c;学习Dart最快…

快速上手Vue

目录 概念 创建实例 插值表达式 Vue响应式特性 概念 Vue是一个用于 构建用户界面 的 渐进式 框架 构建用户界面&#xff1a;基于数据渲染出用户看到的页面 渐进式&#xff1a;Vue相关生态&#xff1a;声明式渲染<组件系统<客户端路由<大规模状态管理<构建工具 V…

云服务器安装Mysql、MariaDB、Redis、tomcat

前置工作 进入根目录 cd / 进入/user/local文件夹 上传压缩包 rz 压缩包 Mysql 1.下载并安装MySQL官方的 Yum Repository wget http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm rpm -ivh mysql-community-release-el7-5.noarch.rpm yum install mysql-…

<计算机网络自顶向下> TCPUDP套接字编程

应用实现&#xff1a;源端的应用进程交换报文实现应用协议&#xff0c;来实现各种各样的网络应用&#xff08;dash&#xff0c;email, etc&#xff09; 而应用层通信不可以直接通信&#xff0c;需要借助下层的服务才可以进行&#xff0c;通过层间接口交给下层&#xff0c;通过…

Linux(Ubuntu) 查看并删除使用【dpkg】安装的软件【mysql 8.3安装失败---原因调查(Depends: libc6 (>= 2.35) but 2.31-0ubuntu9.1)】

目录 ■前言 ■查看安装的软件 ■删除安装的软件 正常删除&#xff08;dpkg -r xxxxName&#xff09; 问题解决&#xff1a;use --purge to remove them too ■其他调查信息 命令 图片1 图片2 图片3 图片4 图片5&#xff08;和镜像库有关&#xff09; 图片6 ■前…

在MOS管栅极前加100Ω电阻,有啥妙用

我们经常会听到在MOSFET栅极前增加一个电阻。那么&#xff0c;为什么要增加这个电阻&#xff0c;进一步地来讲&#xff0c;为什么要增加一个100Ω电阻&#xff1f; 在MOSFET的栅极前增加一个电阻&#xff1f; MOS管是电压型控制器件&#xff0c;一般情况下MOS管的导通&#x…

【学习笔记十五】批次管理和容量管理

一、批次管理 1.配置 SAP EWM 特定参数 激活仓库的批次管理 2.ERP端物料需要启用批次管理 3.EWM物料需要启用批次管理 一般是ERP启用批次管理&#xff0c;相关的配置也会传输到EWM系统 4.建立批次主数据 5.创建采购订单并创建内向交货单&#xff0c;维护批次 6.维护产品主数…

Ubuntu 22.04 开机自动挂载webdav - 设置开机自启脚本 - 解决坚果云webdav无写入权限

效果图&#xff1a; 前言&#xff1a; 1&#xff09;亲测/etc/fstab的办法没有成功自动挂载&#xff0c;换成传统的rc.local可以解决&#xff1b; 2&#xff09;rc-local.service是系统自带的一个开机自启服务&#xff0c;但是在 ubuntu 20.04 上&#xff0c;该服务默认没有开…

NLP_知识图谱_图谱问答实战

文章目录 图谱问答NERac自动机实体链接实体消歧 多跳问答neo4j_graph执行流程结构图![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/1577c1d9c9e342b3acbf79824aae980f.png)company_data![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/20f567d877c743b…

深度学习图像处理基础工具——opencv 实战信用卡数字识别

任务 信用卡数字识别 穿插之前学的知识点 形态学操作 模板匹配 等 总体流程与方法 1.有一个模板 2 用轮廓检测把模板中数字拿出来 外接矩形&#xff08;模板和输入图像的大小要一致 &#xff09;3 一系列预处理操作 问题的解决思路 1.分析准备&#xff1a;准备模板&#…

libbpf-bootstrap库的代码结构介绍(用户层接口介绍),编译链接语句详细介绍,.skel.h文件介绍+示例,bpf程序的后续处理+文件关系总结

目录 libbpf-bootstrap 代码结构介绍 用户层函数 编译 查看 生成内核层的.o文件 第一模块 第二模块 第三模块 第四模块 第五模块 生成辅助文件(.skel.h) 介绍 示例 生成代码层的.o文件 第一模块 第二模块 第三模块 链接出可执行文件 后续总结 libbpf-bootst…

舒欣上门预约系统源码-按摩预约/家政预约全行业适用-小程序/h5/app

上门预约或者到店预约均可&#xff0c;家政&#xff0c;按摩&#xff0c;等等上门类行业均可适用。&#xff08;后台的技师及前台技师这两个字是可以更改的&#xff0c;例如改成家政老师&#xff0c;保洁&#xff0c;等等&#xff09; 视频教程是演示搭建的小程序端&#xff0c…

stm32报错问题集锦

PS&#xff1a;本文负责记录本人日常遇到的报错问题&#xff0c;以及问题描述、原因以及解决办法等&#xff0c;解决办法百分百亲测有效。本篇会不定期更新&#xff0c;更新频率就看遇到的问题多不多了 更换工程芯片型号 问题描述 例程最开始用的芯片型号是STM32F103VE&#…

Abstract Factory抽象工厂模式详解

模式定义 提供一个创建一系列相关或互相依赖对象的接口&#xff0c;而无需指定它们具体的类。 代码示例 public class AbstractFactoryTest {public static void main(String[] args) {IDatabaseUtils iDatabaseUtils new OracleDataBaseUtils();IConnection connection …

微信登录功能-保姆级教学

目录 一、使用组件 二、登录功能 2.1 步骤 2.2 首先找到网页权限 复制demo 代码 这里我们需要修改两个参数 三、前端代码 3.1 api 里weiXinApi.ts 3.2 api里的 index.ts 3.3 pinia.ts 3.4 My.vue 四、后端代码 4.1 WeiXinController 4.2 Access_Token.Java 4.3 We…

SHARE 203S PRO:倾斜摄影相机在地灾救援中的应用

在地质灾害的紧急关头&#xff0c;救援队伍面临的首要任务是迅速而准确地掌握灾区的地理信息。这时&#xff0c;倾斜摄影相机成为了救援测绘的利器。SHARE 203S PRO&#xff0c;这款由深圳赛尔智控科技有限公司研发的五镜头倾斜摄影相机&#xff0c;以其卓越的性能和功能&#…