n个最小和(优先队列)

给出两个包含 n 个整数的数组AB。分别在A,B 中任意出一个数并且相加,可以得到 n^2 个和。求这些和中最小的 n 个。

输入格式

输入第一行一个整数 n(1≤n≤50000)。

接下来一行输入数组 A,用空格隔开。

接下来一行输入数组B,用空格隔开。

1≤Ai,Bi≤10^9

输出格式

从小到大输出最小的n 个和,用空格隔开。

 
  
样例输入
41 3 5 72 4 6 8
样例输出3 5 5 7
解题说明:

1,两个数组比较大,暴力求n^2个所有可能的和,再排序,时间复杂度是n^2logN肯定TLE。

2.这里借助优先队列来完成

首先将两个数组排序,然后就可以知道有上图的不等关系,我们先将B1+Ai压入优先队列中,图上的n^2数中最小的一个肯定在图中最左的一列中,我们取出 并弹出这个数,这就是最小的。然后我们压入其同行中其右边的那个,再重复上述操作n次,这个过程每次取出一个数,取出的n个数就是结果。

3,有个问题是,我取出了一个数,我知道该压入其右边的那个了,这就要记录每个压入的b数组i的下标,用一个结构体实现。不需要记录A数组的下标,压入的是同行的,压数的值sum=sum-bi+bi+1.

#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
int b[50005];
struct ll{
	int ans;
	int wh;
	bool operator <(const ll&Z)const{
	         return ans>Z.ans;
	}
};
priority_queue<int,vector<int>,greater<int> >A;
priority_queue<ll>C;
int main(){
	int n;cin>>n;
	int ip;
	ll l;
	for(int i=1;i<=n;i++){
		cin>>ip;
		A.push(ip);
	}
	for(int i=1;i<=n;i++){
		cin>>ip;
		b[i]=ip;
	}
	sort(b+1,b+n+1,less<int>());
	for(int i=1;i<=n;i++){
		ip=A.top();A.pop();
		l.ans=ip+b[1];l.wh=1;
	    C.push(l);
	}
	int flag=0;
	for(int i=1;i<=n;i++){
		l=C.top();C.pop();
		ip=l.ans;
		int swh=l.wh;
		l.ans=ip-b[swh]+b[swh+1];
		l.wh=swh+1;
		C.push(l);
		if(flag==0){
			cout<<ip;
			flag=1;
		}
		else cout<<" "<<ip;
	}
	cout<<endl;
    return 0;
}


  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值