题目描述
有两个长度都是N的序列A和B,在A和B中各取一个数相加可以得到 N^2N2 个和,求这 N^2N2 个和中最小的N个。
输入输出格式
输入格式:第一行一个正整数N;
第二行N个整数 A_iAi , 满足 A_i\le A_{i+1}Ai≤Ai+1 且 A_i\le 10^9Ai≤109 ;
第三行N个整数 B_iBi , 满足 B_i\le B_{i+1}Bi≤Bi+1 且 B_i\le 10^9Bi≤109 .
【数据规模】
对于50%的数据中,满足1<=N<=1000;
对于100%的数据中,满足1<=N<=100000。
输出格式:输出仅一行,包含N个整数,从小到大输出这N个最小的和,相邻数字之间用空格隔开。
输入输出样例
每个组合数都必须有一个A序列的数和一个B序列的数
以A序列为例,每个数的第一个最优组合都是和B序列的第一个,开一个从小到大的优先队列,储存这n个数,每次弹出一个,第一次弹出的数所对应的B序列中的数必定是B序列中的第一个,那这个A序列中的数的最优组合就变成了加上B序列的第二个数(第一个数已经选过了),将这个数加入优先队列,出n个,就ok
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 100000 + 10;
int a[MAXN] , b[MAXN];
struct f
{
int zhi;
int node;
};
bool operator <(const f &a , const f &b)
{
return a.zhi > b.zhi;
}
priority_queue<f> que;
int main()
{
int n;
cin >> n;
for(int i = 1 ; i <= n ; i ++)
scanf("%d" , &a[i]);
for(int i = 1 ; i <= n ; i ++)
scanf("%d" , &b[i]);
for(int i = 1; i <= n ; i ++)
{
f temp;
temp.zhi = a[i] + b[1];
temp.node = 1;
que.push(temp);
}
for(int i = 1; i <= n ; i ++)
{
f temp = que.top();
que.pop();
if(temp.node + 1 <= n)
{
f t;
t.node = temp.node + 1;
t.zhi = temp.zhi - b[temp.node] + b[temp.node + 1];
que.push(t);
}
printf("%d" , temp.zhi);
if(i != n)
printf(" ");
}
return 0;
}