题目描述
有两个长度为N的序列A和B,在A和B中各任取一个数相加可以得到N2个和,求这N2个和中最小的N个。
输入
第一行输入一个正整数N(1<=N<=100000);
第二行N个整数Ai且Ai<=109;第三行N个整数Bi且Bi<=109。
输出
输出仅一行,包含n个整数,从小到大输出这n个最小的和,相邻数字之间用空格隔开。
样例输入
51 3 2 4 56 3 4 1 7
样例输出
2 3 4 4 5
思路:这道题是训练指南上k个最小和的变形题,优先队列的应用。
先将两个数组进行升序排序,由于我们并不清楚到底是a数组的n个值加b数组的最小值小,还是b数组的n个值加a数组的最小值小(这个说法其实并不严谨,不过,这是唯一让我瞬间懂了如何用优先队列实现思路的说法),所以我们需要滚动进行存储,比赛的时候,我错在进行循环比较,因为这样忽略了有可能存在之后有更小值小于之前的值,而我已经将之前的值存入了数组,所以会出错。
改天写个stl优先队列的用法模板
#include<stdio.h>
#include<queue>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn = 100010;
int a[maxn],b[maxn],vis[maxn];
struct node{
int s,b;
node (int s,int b) : s(s),b(b){}//结构体赋值
bool operator < (const node &ch) const {
return s > ch.s ;
}//自定义优先队列 s小的优先级高
};
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
for(int i = 0; i < n; i ++)
scanf("%d",&a[i]);
for(int i = 0; i < n; i ++)
scanf("%d",&b[i]);
priority_queue<node>Q;
sort(a,a+n);
sort(b,b+n);
for(int i = 0; i < n; i ++)
Q.push(node(a[i]+b[0],0));
for(int i = 0; i < n; i ++)
{
node s = Q.top();
vis[i] = s.s ;
Q.pop();
int num = s.b ;
int sum = s.s ;
if(num+1 < n )
Q.push(node(sum-b[num]+b[num+1],num+1));
}
for(int i = 0; i < n-1; i ++)
printf("%d ",vis[i]);
printf("%d\n",vis[n-1] );
}
return 0;
}