题目描述
有两个长度都是N的序列A和B,在A和B中各取一个数相加可以得到N^2个和,求这N^2个和中最小的N个。
输入格式:
第一行一个正整数N;
第二行N个整数Ai,满足Ai<=Ai+1且Ai<=10^9;
第三行N个整数Bi, 满足Bi<=Bi+1且Bi<=10^9.
[数据规模]
对于50%的数据中,满足1<=N<=1000;
对于100%的数据中,满足1<=N<=100000。
输出格式:
输出仅一行,包含N个整数,从小到大输出这N个最小的和,相邻数字之间用空格隔开。
Solution
类似之前的最小函数值,分别记录第一排乘到哪一位,每次取堆顶然后后移压入
Code
#include <stdio.h>
#include <string.h>
#include <queue>
#include <vector>
#include <algorithm>
#define rep(i, st, ed) for (int i = st; i <= ed; i += 1)
#define drp(i, st, ed) for (int i = st; i >= ed; i -= 1)
#define fill(x, t) memset(x, t, sizeof(x))
#define N 100001
using std:: vector;
vector<int> v;
vector<int> a;
struct rec{
int x, cal;
bool operator <(const rec &b) const{
rec a = *this;
return a.x + v[a.cal] > b.x + v[b.cal];
}
};
inline int read(){
int num = 0, v = 1;
char ch = getchar();
while (ch < '0' || ch > '9'){
if (ch == '-'){
v = -1;
}
ch = getchar();
}
while (ch >= '0' && ch <= '9'){
num = (num << 1) + (num << 3) + ch - '0';
ch = getchar();
}
return num * v;
}
using std:: priority_queue;
int main(void){
int n = read();
priority_queue<rec> heap;
rep(i, 1, n){
int x = read();
a.push_back(x);
}
rep(i, 1, n){
int x = read();
v.push_back(x);
}
sort(v.begin(), v.end());
drp(i, n - 1, 0){
heap.push((rec){a[i], 0});
}
while (n --){
rec prt = heap.top(); heap.pop();
printf("%d ", prt.x + v[prt.cal]);
heap.push((rec){prt.x, prt.cal + 1});
}
printf("\n");
return 0;
}