给出两个包含n个整数的数组A,B。分别在A,B中任意出一个数并且相加,可以得到 n2个和。求这些和中最小的n个。
输入格式
输入第一行一个整数 n(1≤n≤50000)。
接下来一行输入数组A,用空格隔开。
接下来一行输入数组B,用空格隔开。
1≤Ai,Bi≤109
输出格式
从小到大输出最小的n个和,用空格隔开。
样例输入
4
1 3 5 7
2 4 6 8
样例输出
3 5 5 7
解题思路:
表1: A1+B1≤A1+B2≤A1+B3≤……≤A1+Bn
表2: A2+B1≤A2+B2≤A2+B3≤……≤A2+Bn
表3: A3+B1≤A3+B2≤A3+B3≤……≤A3+Bn
....
表n: An+B1≤An+B2≤An+B3≤……≤An+Bn
首先将两个数组排序,得到上图的不等关系,我们先将B1和Ai压入队列(即第一列),
A1+B1肯定是最小的,输出并弹出它,然后将他右面一个入队,然后弹出队列最小的(既
优先队列队首元素),找到后输出并弹出它,将他右面一个入队,一直继续这个步骤,
直到输出n个元素
#include <iostream>
#include <queue>
#include<algorithm>
using namespace std;
struct node{
int sum,a,b;
bool operator < (const node & x) const
{/*优先级重载,sum越小的优先级越高*/
return sum>x.sum;
}
};
int main(){
int n;
int a[50001],b[50001];
priority_queue<node>q;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=n;i++){
cin>>b[i];
}
/*分别从小到大排序a和b数组*/
sort(a+1,a+1+n);
sort(b+1,b+1+n);
for(int i=1;i<=n;i++){
node nn;
nn.a=i;
nn.b=1;
nn.sum=a[i]+b[1];
/*将 (A[i]+B[1],i,1)入队*/
q.push(nn);
}
for(int i=1;i<=n;i++){
node nn,nnn;
/*在队中取出一个结构 (sum,a,b),取出的sum则为第i个最小和*/
nn=q.top();
if(i!=1) cout<<" ";
cout<<nn.sum;
q.pop();
nnn.sum=a[nn.a]+b[nn.b+1];
nnn.a=nn.a;
nnn.b=nn.b+1;
q.push(nnn);
/*把结构 (A[a]+B[b+1],a,b+1)重新入队*/
}
return 0;
}