146. 序列

题意:

有t个测试用例。

每个测试用例,包含m个数组,每个数组包含n个数字。你可以从每个数组里面选择一个数字,然后将m个数字加和得到一个数字。用这样的方式一共可以获得n的m次幂个数字。问,在这么多个数字中选出最小的n个数字。

思路:

老规矩,我们还是先看一下最笨的做法是什么。那就是将所有的组合全部遍历得到,然后选出最小的n个数字。

然后你就会发现,这么多个数字,开不了这么大的内存将他们存下来。那怎么办呢?

你就会想到一个只有n个空间的数组不就行了,先用第一排的第一个数字,加上第二排的n个数字,得到了最初的n个数字。然后,你就发现没有然后了。因为下一步你就不知道怎么做了。

因为第一排的那个数字,你不知道他在第一排里面是多大,所以和第二排加和后你也不知道这些数字和第一排其他数字加上第二排相比是怎样的个大小关系。

那这里你就会想到,我把第一排先排个序,再和第二排进行加和,那这次得到的n个数字不就是a0为基础的n个数了么。但这时还是有个问题,就是最小的数肯定是这两排里面所有加和数字的最小,但是第二小并不一定存在在这里面。也就是说倒数第二小的数字可能不是a0加上第二排的数字得到的。

所以这时候你就需要一个操作,假设说a0 + bi 是最小值,那倒数第二小是哪个数呢?
就是a1+bi 么?

不一定,应该是a1+bi 和a0+{b0~bn}(除bi外)所有数比较之后的那个最小值。

好,按照这个操作,假设a1+bi 和a0加其他数比较后确实是最小值,那倒数第三小的值是什么呢?

没错,就是a2+bi和a0+{b0~bn}(除bi外)所有数比较之后的那个最小值。假设a0+bj 是倒数第三小的值,那倒数第四小的值是什么呢?

思考一下

没错,就是a0+{b0~bn}(除bi , bj外)和a2+bi 和 a1+bj 比较之后的那个最小值。

好的,相信到这里,你已经明白了两个序列得到最小的n个值的做法。那问题来了,题目要求的是m个序列的最小的n个值,这可怎么办呢??

我相信你已经有了答案。就是按照上面的做法,两两进行比较就可以得到了啊!!!

如果你没想明白,那我就稍微点拨你一下。当你用上面的做法,可以得到 n 个最小的数字,这是没有问题的吧。然后,这 n 个数字,不就相当于你已经排好序的从小到大的第一排数字嘛,你接下来得到的第三排序列,不就相当于刚刚第二排的序列嘛?这不又是一个两两序列求最小的n个值的问题了嘛!!!!

ok,话不多说,上代码


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5+10;typedef pair<int , int> PII;int n , m;
int a[N] , b[N] , c[N];void merge(){priority_queue<PII , vector<PII> , greater<PII>> heap;//定义一个小根堆,里面的元素都是按照第一个元素从小到大排列的//里面元素是{x,y},x是a[i]+b[j],y是ifor(int i = 0 ; i < n ; i++){heap.push({a[0] + b[i] , 0});}//首先用最小的数字加上b排数字,放入小根堆中for(int i = 0 ; i < n ; i++){auto t = heap.top();heap.pop();int s = t.first , p = t.second;//取出当前最小的值,s是值的大小,t是a的下标ic[i] = s;//将最小的值先保存在c数组中heap.push({s-a[p]+a[p+1] , p+1});//将a[i+1]+b[j]放入小根堆中,继续跟其他数比大小,p从i变成i+1}for(int i = 0 ; i < n ; i++)a[i] = c[i];//将临时数组c的值赋值给a,a里面就是每次两两序列比较后从小到大排序的最小n个数
}int main(){int t;cin >> t;while(t--){cin >> m >> n;//得到第一排序列for(int i = 0 ; i < n ; i++)scanf("%d",&a[i]);sort(a , a+n);for(int i = 0 ; i < m-1 ; i++){//接下来的每排序列都当作第二排for(int j = 0 ; j < n ; j++)scanf("%d" , &b[j]);merge();//两个序列进行比较,得到n个最小值}for(int i = 0 ; i < n ;  i++){printf("%d ",a[i]);}puts("");}return 0;
}

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

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

相关文章

[leetcode]28. 找出字符串中第一个匹配项的下标

前言&#xff1a;力扣刷题 问题&#xff1a; 给你两个字符串 haystack 和 needle &#xff0c;请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标&#xff08;下标从 0 开始&#xff09;。如果 needle 不是 haystack 的一部分&#xff0c;则返回 -1 。 示例&…

全面对比API和SDK

目录 全面对比API和SDK1. 介绍2. API和SDK的基本概念3. API与SDK的区别4. API与SDK的优缺点对比5. API与SDK的使用场景6. API与SDK的开发和维护成本7. API与SDK的集成和实现方式8. API与SDK的安全性9. API与SDK的性能比较10. API与SDK的选择建议11. 总结 全面对比API和SDK 1. …

【Linux】进程管理:进程及概念精讲

前言&#xff1a;本节内容包含进程管理操作的各种基础概念精讲&#xff0c;同时部分板块包含Linux操作系统与一般操作系统的概念对比。不仅包含“书面概念”&#xff0c;还包含详细操作以及通俗讲解。 目录 一、进程概念引入 二、进程的描述与组织&#xff1a;进程控制块&…

nodejs的express编写http服务器配置跨域

配置跨域可引入cors包&#xff0c;插入到express的中间件中 1.引入cors包 npm install cors2. 使用cors 插入到中间件中 const app express()const corsOptions {origin: http://localhost:5173, // 允许访问的来源&#xff0c;可以是单个字符串或一个数组methods: [PUT],…

【python】《流畅的python》读书笔记之第1-2章

序 《流畅的python》是还在上学时就被安利的一本奇书&#xff0c;马克了很久一直没机会系统拜读。最近碰巧偶得第二版的pdf。经济周期的下行阶段正是用来学习充电的&#xff0c;于是乎打算捡起荒废许久的blog&#xff0c;读读书&#xff0c;写写字&#xff0c;蓄势待东风。 第…

xftp突然无法连接虚拟机

问题描述 使用xftp连接虚拟机的时候一直显示 连接xxx.xxx.xx.xx失败 问题原因查找 首先打开本地cmd命令提示符 ping 你的虚拟机ip地址 我的是 ping 192.168.xx.xx 显示请求超时 解决方案&#xff1a; 点击打开更改适配器选项 右键vmnet 8——属性 如图前四个选项必选 单…

《操作系统导论》第16章读书笔记:分段

《操作系统导论》第16章读书笔记&#xff1a;分段 —— 杭州 2024-03-31 夜 文章目录 《操作系统导论》第16章读书笔记&#xff1a;分段0.前言1.分段&#xff1a;泛化的基址/界限2.我们引用哪个段&#xff1f;3.栈怎么办4.支持共享5.细粒度与粗粒度的分段、操作系统支持6.小结7…

Unix中的进程和线程-1

目录 1.如何创建一个进程 2.如何终止进程 2.2遗言函数 3.进程资源的回收 4.孤儿进程和僵尸进程 孤儿进程 (Orphan Process)&#xff1a; 僵尸进程 (Zombie Process)&#xff1a; 代码示例&#xff1a; 5. 进程映像的更新 在Linux中&#xff0c;进程和线程是操作系统进行工作调…

CAS 的 ABA 问题

一、什么是 ABA 问题 ABA 的问题: 假设存在两个线程 t1 和 t2. 有⼀个共享变量 num, 初始值为 A. 接下来, 线程 t1 想使⽤ CAS 把 num 值改成 Z, 那么就需要 先读取 num 的值, 记录到 oldNum 变量中. 使⽤ CAS 判定当前 num 的值是否为 A, 如果为 A, 就修改成 Z. 但是, 在…

CaT论文翻译

CaT: Balanced Continual Graph Learning with Graph Condensation CaT&#xff1a;通过图压缩实现平衡的连续图学习 Abstract 持续图学习(CGL)的目的是通过以流方式输入图数据来持续更新图模型。由于模型在使用新数据进行训练时很容易忘记以前学到的知识&#xff0c;因此灾…

Python提取文本文档符合条件的某列

Python在日常使用中会有处理txt文本文件的情况&#xff0c;对于文本文件&#xff0c;实际上也是对文件中字符串的处理过程。 实例&#xff1a;有一个文本文件a.txt,文本内容如下图所示&#xff0c;现在需要提取大于15的某列的整行。 a.txt内容如下&#xff1a; A: 1 B: 19 C:…

Linux进程的基本概念

冯诺依曼体系结构 我们常见的计算机&#xff0c;如笔记本。我们不常见的计算机&#xff0c;如服务器&#xff0c;大部分都遵守冯诺依曼体系。 截至目前&#xff0c;我们所认识的计算机&#xff0c;都是有一个个的硬件组件组成 输入单元&#xff1a;包括键盘 , 鼠标&#xf…

基于SSM的宠物医院信息管理系统

项目简介 主要功能包括首页、个人中心、用户管理、医学知识管理、科室信息管理、医生信息管理、订单信息管理等。 管理员模块:管理员登录进入宠物医院信息管理系统可以查看个人中心、用户管理、医生管理、医学知识管理、科室信息管理、医生信息管理、预约挂号管理、医嘱信息管理…

AtCoder Beginner Contest 342 A - D

A - Yay! 大意 给定字符串&#xff0c;其中有且仅有一个字符与其他不同&#xff0c;输出这个字符的下标&#xff08;从1开始&#xff09;。 思路 桶排序统计次数即可。 代码 #include<iostream> #include<vector> using namespace std; int main(){string s;…

请解释Java中的深拷贝和浅拷贝的区别。请解释Java中的构造器链式调用及其实现方式。

请解释Java中的深拷贝和浅拷贝的区别。 在Java中&#xff0c;深拷贝和浅拷贝是两种处理对象复制的方式&#xff0c;它们的主要区别在于如何处理对象内部的引用类型字段。理解这两种拷贝方式对于避免潜在的问题&#xff08;如数据不一致或内存泄漏&#xff09;非常重要。 浅拷…

【前端面试3+1】06继承方式及优缺点、缓存策略、url输入到渲染全过程、【二叉树中序遍历】

一、继承有哪些方式&#xff1f;以及优缺点 继承的方式包括原型链继承、构造函数继承、组合继承、原型式继承、寄生式继承和组合式继承。 1.原型链继承&#xff1a; 实现方式&#xff1a;将子类的原型指向父类的实例来实现继承。优点&#xff1a;简单易懂&#xff0c;代码量少。…

如何制作伸缩侧边栏?

目录 一、html-body 二、CSS 三、JS 四、完整代码 五、效果展示 一、html-body 侧边栏的伸缩需要用户触发事件&#xff0c;这里使用button为例&#xff0c;用户点击按钮实现侧边栏的打开和关闭。 <body><!-- 按钮&#xff0c;可以用文字、图片等作为事件源&am…

【JavaScript编程】前端如何实现局部打印(精确打印)

在前端开发中实现精确打印控制&#xff08;局部打印&#xff09;&#xff0c;可以通过以下几种方式&#xff1a; 一、使用window.print()和id选择器 将需要打印的内容包裹在一个容器内&#xff0c;比如一个<div>标签&#xff0c;并为该容器设置一个ID。 <div id&quo…

三个js算法

① 冒泡排序   作为最简单的排序算法之一&#xff0c;冒泡排序给我的感觉就像Abandon在单词书里出现的感觉一样&#xff0c;每次都在第一页第一位&#xff0c;所以最熟悉。冒泡排序还有一种优化算法&#xff0c;就是立一个flag&#xff0c;当在一趟序列遍历中元素没有发生交换…

027-033前缀和

027-033前缀和 核心思想:前缀和-->快速得到某段连续区间的结果 方法:初始化dp数组 前缀和哈希表 dp[i][j] dp[i-1][j]dp[i][j-1]arr[i][j]-dp[i-1][j-1]; 求dp[i][j] dp[x2][y2] - dp[x1-1][y2] - dp[x2][y1-1] dp[x1-1][y1-1] (x1,y1)>(x2,y2) DP34 【模板】一维前…