给出两个包含 n 个整数的数组A,B。分别在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;
}