序列合并(最小的n个数)

序列合并

题目描述

有两个长度为 N N N单调不降序列 A , B A,B A,B,在 A , B A,B A,B 中各取一个数相加可以得到 N 2 N^2 N2 个和,求这 N 2 N^2 N2 个和中最小的 N N N 个。

输入格式

第一行一个正整数 N N N

第二行 N N N 个整数 A 1 … N A_{1\dots N} A1N

第三行 N N N 个整数 B 1 … N B_{1\dots N} B1N

输出格式

一行 N N N 个整数,从小到大表示这 N N N 个最小的和。

样例 #1

样例输入 #1

3
2 6 6
1 4 8

样例输出 #1

3 6 7

提示

对于 50 % 50\% 50% 的数据, N ≤ 1 0 3 N \le 10^3 N103

对于 100 % 100\% 100% 的数据, 1 ≤ N ≤ 1 0 5 1 \le N \le 10^5 1N105 1 ≤ a i , b i ≤ 1 0 9 1 \le a_i,b_i \le 10^9 1ai,bi109

#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
const int N=1e5+10;
using namespace std;
vector <int> a;
vector <int> b;
priority_queue<int>q;//这里必须要默认从小到大排序,否则获取的top是最小值无法与后面算的值比较 
int main()
{
	int n;
	cin>>n;
	int x;
	for(int i=0;i<n;i++)
	{
		cin>>x;
		a.push_back(x);
	}
	sort(a.begin(),a.end());
	for(int i=0;i<n;i++)
	{
		cin>>x;
		b.push_back(x);
	}
	sort(b.begin(),b.end());
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			auto v=a[i]+b[j];
			if(q.size()<n)//我们只要n个数
			{
				q.push(v);
			}
			else//有了n个数,还要判断这n个数是不是最小的
			{
				if(q.top()>v)//因为优先队列默认从小到大排序,所以队列顶端top是最大值,如果最大值比新的值大,我们删除top值增加v
				{
					q.pop();
					q.push(v);
				}
				else//如果最大值小于当前这个v,那么b数组后面的都不用加了,因为a,b都是排序了的,越往后面越大,我们不需要大的值
					break;
			}
		}
	}
	int ans[N];
	for(int i=n-1;i>=0;i--)
	{
		ans[i]=q.top();//队列是从小到大排序的,top是最大值,先存入数组中
		q.pop();
	}
	for(int i=0;i<n;i++)//反向输出
	{
		cout<<ans[i]<<" ";
	}
	return 0;
}```

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值