三元组的最小距离

题目链接: 三元组最小距离

定义三元组 $(a, b, c)$($a,b,c$ 均为整数)的距离 $D=|a-b|+|b-c|+|c-a|$。

给定 $3$ 个非空整数集合 $S_1, S_2, S_3$,按升序分别存储在 $3$ 个数组中。

请设计一个尽可能高效的算法,计算并输出所有可能的三元组 $(a, b, c)$($a \in S_1,b \in S_2,c \in S_3$)中的最小距离。

例如 $S_1=\{-1, 0, 9\}, S_2=\{-25, -10, 10, 11\}, S_3=\{2, 9, 17, 30, 41\}$ 则最小距离为 $2$,相应的三元组为 $(9,10,9)$。

输入格式

第一行包含三个整数 $l,m,n$,分别表示 $S_1,S_2,S_3$ 的长度。

第二行包含 l 个整数,表示 $S_1$ 中的所有元素。

第三行包含 $m$ 个整数,表示 $S_2$ 中的所有元素。

第四行包含 $n$ 个整数,表示 $S_3$ 中的所有元素。

以上三个数组中的元素都是按升序顺序给出的。

输出格式

输出三元组的最小距离。

数据范围

$1 \le l,m,n \le 10^5$,
所有数组元素的取值范围 $[-10^9,10^9]$。

输入样例:
3 4 5
-1 0 9
-25 -10 10 11
2 9 17 30 41
输出样例:
2
  • 暴力想法: 枚举所有可能的答案排列 从小到大 [S1 S2 S3], [S3 S2 S1], [S2, S3, S1], [S1, S3, S2], [S2, S1, S3], [S3, S1, S2], 如果单纯暴力复杂度就是O(6n^3) 铁定过不了,这时候我们可以选择枚举中间值属于哪个素组, 在每个枚举中我们已经确定了中间的数,那么我们就可以根据这个中间值在另外两个数组中二分找到符合排列的数,这里又有两个前后问题,我们还是直接枚举比较,比如确定中间的数来自于S2,那么答案排列可能是S1,S2,S3, 或者 S3, S2, S1这样算下来总的时间复杂度O(3nlogn).

  • 代码


#include<bits/stdc++.h>
using namespace std;const int N = 1e5 + 10;
typedef long long LL;int main()
{int l, n, m; cin >> l >> n >> m;vector<int> a(l), b(n), c(m);for(int i = 0; i < l; i ++) cin >> a[i];for(int i = 0; i < n; i ++) cin >> b[i];for(int i = 0; i < m; i ++) cin >> c[i];// a中元素当中间值LL ans = 1e12;for(auto it : a){//b a cint dexb = upper_bound(b.begin(), b.end(), it) - b.begin();if(dexb != 0) dexb --;int dexc = lower_bound(c.begin(), c.end(), it) - c.begin();if(dexc == c.size()) dexc --;int xa = it, xb = b[dexb], xc = c[dexc];ans = min(ans, 1ll*abs(xa - xb) + abs(xa - xc) + abs(xb - xc));//c a bdexc = upper_bound(c.begin(), c.end(), it) - c.begin();if(dexc != 0) dexc --;dexb = lower_bound(b.begin(), b.end(), it) - b.begin();if(dexb == b.size()) dexb --;xa = it, xb = b[dexb], xc = c[dexc];ans = min(ans, 1ll*abs(xa - xb) + abs(xa - xc) + abs(xb - xc));}// b 当中间值for(auto it : b){//a b cint dexa = upper_bound(a.begin(), a.end(), it) - a.begin();if(dexa != 0) dexa --;int dexc = lower_bound(c.begin(), c.end(), it) - c.begin();if(dexc == c.size()) dexc --;int xb = it, xa = a[dexa], xc = c[dexc];ans = min(ans, 1ll*abs(xa - xb) + abs(xa - xc) + abs(xb - xc));//c b adexc = upper_bound(c.begin(), c.end(), it) - c.begin();if(dexc != 0) dexc --;dexa = lower_bound(a.begin(), a.end(), it) - a.begin();if(dexa == a.size()) dexa --;xb = it, xa = a[dexa], xc = c[dexc];ans = min(ans, 1ll*abs(xa - xb) + abs(xa - xc) + abs(xb - xc));}// c 当中间值for(auto it : c){//a c bint dexa = upper_bound(a.begin(), a.end(), it) - a.begin();if(dexa != 0) dexa --;int dexb = lower_bound(b.begin(), b.end(), it) - b.begin();if(dexb == b.size()) dexb --;int xc = it, xa = a[dexa], xb = b[dexb];ans = min(ans, 1ll*abs(xa - xb) + abs(xa - xc) + abs(xb - xc));//b c adexb = upper_bound(b.begin(), b.end(), it) - b.begin();if(dexb != 0) dexb --;dexa = lower_bound(a.begin(), a.end(), it) - a.begin();if(dexa == a.size()) dexa --;xc = it, xa = a[dexa], xb = b[dexb];ans = min(ans, 1ll*abs(xa - xb) + abs(xa - xc) + abs(xb - xc));}cout << ans << endl;return 0;
}

  • 另一个思路:滑动窗口 O(3n*log(3n))实现
    我们可以标记好每个数来自哪个数组然后统一排序,滑动窗口找相邻三个不同归属的数进行答案比较,这个和上面的相比实现更简单些!
  • 代码

#include<bits/stdc++.h>
using namespace std;const int N = 1e5 + 10;
typedef long long LL;int main()
{int l, n, m; cin >> l >> n >> m;// 可以结构体数组,或者pair 存数值与所属关系,用multimap纯属个人偷懒行为multimap<int, int> cnt;for(int i = 0; i < l; i ++) {int x; cin >> x;cnt.insert(pair<int, int>(x, 1));}for(int i = 0; i < n; i ++){int x; cin >> x;cnt.insert(pair<int, int>(x, 2));}for(int i = 0; i < m; i ++){int x; cin >> x;cnt.insert(pair<int, int>(x, 3));}LL ans = 1e18;vector<LL> st(4, 1e10);// 将st1,2,3赋值1e10表示空for(auto [a,b] : cnt){st[b] = a;if(st[1] != 1e10 && st[2] != 1e10 && st[3] != 1e10){ans = min(ans, 1ll*abs(st[1]-st[2]) + abs(st[1]-st[3]) + abs(st[2]-st[3]));}}cout << ans << endl;return 0;
}

  • 进阶思路:O(3n)实现 三路归并
    假设x < y < z 我们化简 |x-y|+|y-z|+|z-x| 后发现 我们每一次算出的答案都是2*(max-min)
    所以我们只需要每个三元组中的最大值与最小值即可,所以我们尽可能让max与min逼近
    这时候就可以三路归并,每次只让最小的去靠近最大的值,实现也很简单。
  • 代码

#include<bits/stdc++.h>
using namespace std;const int N = 1e5 + 10;
typedef long long LL;int main()
{int l, n, m; cin >> l >> n >> m;vector<int> a(l), b(n), c(m);for(int i = 0; i < l; i ++) cin >> a[i];for(int i = 0; i < n; i ++) cin >> b[i];for(int i = 0; i < m; i ++) cin >> c[i];LL ans = 1e18;for(int i = 0, j = 0, k = 0; i < l && j < n && k < m;){int x = a[i], y = b[j], z = c[k];ans = min(ans, 2*(1ll*max(x, max(y, z)) - min(x, min(y, z))));if(x <= y && x <= z) i ++;else if(y <= x && y <= z) j ++;else k ++;}cout << ans << endl;return 0;
}

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

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

相关文章

AI学习集合-前瞻

AI学习前瞻 工作岗位 算法工程师机器学习工程师图像算法工程师ai工程师NLP高级算法工程师 学习路线 应用场景 计算机视觉技术应用场景 自然语言应用 AI流程 AI拟人流程 机器人历史数据经验模型规律依据模型预测未来依据规律做出判断 AI基本流程 术语所用到的技术手段数据数…

javascript中对包含关系判断介绍

本文将为您详细讲解 JavaScript 中对包含关系的判断&#xff0c;包括数组、字符串等&#xff0c;并提供相应的代码例子。 1. 数组包含关系判断 在 JavaScript 中&#xff0c;数组包含关系判断通常使用 Array.prototype.includes() 方法。这个方法返回一个布尔值&#xff0c;表示…

牛客网C++专项题目整理(2)

1.参加位运算的数据可以是任何类型的数据。请问这句话的说法是正确的吗&#xff1f; 答案&#xff1a;错误 位运算符主要用于整型数据&#xff08;如int、unsigned int、long、unsigned long等&#xff09;和字符型数据&#xff08;如char和unsigned char&#xff09;&#x…

mac 本地使用dockerfile启动 springboot项目

1.创建Dockerfile放在项目的根目录下 2.编写Dockerfile FROM openjdk:11 MAINTAINER ChengLinADD target/JiaLi-0.0.1-SNAPSHOT.jar /app.jar# 暴露 Spring Boot 应用的端口号 EXPOSE 8088 # 启动 Spring Boot 应用 CMD ["java", "-jar", "app.jar&q…

前端学习第四天-css提升

达标要求 掌握css复合选择器 块级元素和行内元素及行内块的区别? 哪些元素是块元素,行内元素及行内块元素? 熟练掌握display的用法 能够说出css三大特性 熟练运用背景样式 1. CSS复合选择器 复合选择器是由两个或多个基础选择器&#xff0c;通过不同的方式组合而成的…

vue2结合electron开发跨平台应用(桌面端应用)

1.确定nodejs和electron的版本号 确定nodejs和electron的版本号及其重要&#xff0c;因为electron的开发版本需要指定的nodejs版本支持。 本文安装测试使用的是: 1.node18.19.0 2.npm10.2.3 3.vue-cli5.0.8 4.electron29.0.0 2.创建vue2项目 vue create elctron29.0.0_no…

zotero | 多平台同步 | 坚果云

zotero注册登陆 打开zotero软件&#xff0c;mac电脑打开首选项&#xff0c;如下图所示&#xff1a; 然后点击同步选项&#xff0c;如下图所示&#xff0c;如果已经有账号&#xff0c;请登陆账号&#xff0c;无则注册账号之后再登陆&#xff1b; 注册坚果云账号 注册完坚果…

求最短路径之BF算法

介绍 全称Bellman-Ford算法&#xff0c;目的是求解有负权边的最短路径问题。 考虑环&#xff0c;根据环中边的边权之和的正负&#xff0c;将环分为零环、正环、负环。其中零环、正环不会影响最短路径的求解&#xff0c;而负环会影响最短路径的求解。 可用BF算法返回一个bool值…

暗黑大气MT苹果CMS MT主题源码-PC版适用于苹果CMS V10

苹果CMS MT主题是一款多功能的主题&#xff0c;适用于苹果CMS V10的暗黑大气风格。 地 址 &#xff1a; runruncode.com/houtai/19704.html 初次使用说明&#xff1a; 在后台设置中&#xff0c;选择MT主题&#xff0c;并在模板目录中填写HTML。 后台地址为&#xff1a;MT主题…

*JAVAWEB--maven*

一:介绍: maven是一种专门管理以及构建JAVA项目的一个工具,maven屹立这么久也是因为其有三个非常好用的功能: 1.提供标准化的项目结构 比方说平时我们编写JAVA项目的时候,如果想把原本在eclipse当中编写的项目导入到IDEA当中进行使用,就会导致报错,因为这两个的项目结构并不一样…

图神经网络实战——基于DeepWalk创建节点表示

图神经网络实战——基于DeepWalk创建节点表示 0. 前言1. Word2Vec1.1 CBOW 与 skip-gram1.2 构建 skip-gram 模型1.3 skip-gram 模型1.4 实现 Word2Vec 模型 2. DeepWalk 和随机行走3. 实现 DeepWalk小结系列链接 0. 前言 DeepWalk 是机器学习 (machine learning, ML) 技术在图…

[Angular 基础] - routing 路由(上)

[Angular 基础] - routing 路由(上) 之前部分 Angular 笔记&#xff1a; [Angular 基础] - 生命周期函数 [Angular 基础] - 自定义指令&#xff0c;深入学习 directive [Angular 基础] - service 服务 终于到 routing 了……这部分的内容比我想象的要复杂很多&#xff0c;果…

LC打怪录 选择排序 215.Kth Largest Element in an Array

题目链接&#xff1a;力扣 选择排序知识 设第一个元素为比较元素&#xff0c;依次和后面的元素比较&#xff0c;比较完所有元素并找到最小元素&#xff0c;记录最小元素下标&#xff0c;和第0个下表元素进行交换。在未排序区域中&#xff0c;重复上述操作&#xff0c;以此类推…

力扣每日一题 用队列实现栈 模拟

Problem: 225. 用队列实现栈 文章目录 思路复杂度Code 思路 &#x1f468;‍&#x1f3eb; 力扣官解 辅助队列存栈顶元素主队列存逆序序列 复杂度 时间复杂度: 添加时间复杂度, 示例&#xff1a; O ( n ) O(n) O(n) 空间复杂度: 添加空间复杂度, 示例&#xff1a; O ( …

js监听网页iframe里面元素变化其实就是监听iframe变化

想要监听网页里面iframe标签内容变化&#xff0c;需要通过监听网页dom元素变化&#xff0c;然后通过查询得到iframe标签&#xff0c;再通过iframe.contentWindow.document得到ifram内的document&#xff0c;然后再使用选择器得到body元素&#xff0c;有了body元素&#xff0c;就…

2024年华为OD机试真题-贪吃的猴子-Python-OD统一考试(C卷)

题目描述: 一只贪吃的猴子,来到一个果园,发现许多串香蕉排成一行,每串香蕉上有若干根香蕉。每串香蕉的根数由数组numbers给出。猴子获取香蕉,每次都只能从行的开头或者末尾获取,并且只能获取N次,求猴子最多能获取多少根香蕉。 输入描述: 第一行为数组numbers的长度 第二…

Java和JavaScript之间的主要区别与联系

目录 概况 主要区别 联系 总结 概况 Java和JavaScript&#xff0c;尽管名字相似&#xff0c;但它们在编程世界中却扮演着截然不同的角色。Java&#xff0c;一种强类型、面向对象的编程语言&#xff0c;广泛应用于企业级应用和安卓应用开发。它的设计理念是一次编写&#x…

使用协程库httpx并发请求

httpx和aiohttp都是比较常用的异步请求库&#xff0c;当然requests多线程或requestsgevent也是不错的选择。 一个使用httpx进行并发请求的脚本如下&#xff1a; import functools import sys import timeimport anyio import httpxasync def fetch(client, results, index) -…

详解 JavaScript 中的数组

详解 JavaScript 中的数组 创建数组 注&#xff1a;在JS中的数组不要求元素的类型&#xff0c;元素类型可以一样&#xff0c;也可以不一样 1.使用 new 关键字创建 let array new Array()2.使用字面量方式创建(常用) let array1 [1,2,3,"4"]获取数组元素 使用下…

西安-腾讯云-Python面试经验--一面凉经

自我介绍手撕链表排序操作系统 a. 线程和进程区别 b. 线程安全 c. 如何保证线程安全 d. 线程崩溃&#xff0c;会不会影响所在的进程 e. 什么是守护进程&#xff0c;僵尸进程&#xff0c;孤儿进程 f. 如何产生一个守护进程 g. 如何避免僵尸进程或者孤儿进程redis a. 持久化方式有…