知识点:堆,数学归纳法
这个题是两个序列合并的升级版,首先我们要会两个序列合并,然后我们拿合并完的序列和第三个序列合并,得到新的最小值序列,这样一直合并下去,最后得到的就是最值的序列,
一个编程的细节就是我们输出答案的数组一开始也是要赋值的,因为输入的序列可能只有一个的情况
#include <bits/stdc++.h>
using namespace std;
const int N = 2005;
int a[N], b[N], c[N];
struct node {
int x, y, flag;
node() {}
node(int a, int b, int c): x(a), y(b), flag(c) {}
bool operator < (const node &t) const {
return a[x] + b[y] > a[t.x] + b[t.y];
}
};
int main() {
int T;
cin >> T;
while (T--) {
int m, n;
cin >> m >> n;
for (int i = 1; i <= n; i++) scanf("%d", a + i);
sort(a + 1, a + n + 1);
for (int i = 1; i <= n; i++) c[i] = a[i];
while (--m) {
for (int i = 1; i <= n; i++) scanf("%d", b + i);
sort(b + 1, b + n + 1);
priority_queue<node> q;
q.push(node(2, 1, 0));
q.push(node(1, 2, 1));
c[1] = a[1] + b[1];
for (int i = 2; i <= n; i++) {
node now = q.top(); q.pop();
c[i] = a[now.x] + b[now.y];
q.push(node(now.x, now.y + 1, 1));
if (!now.flag) q.push(node(now.x + 1, now.y, 0));
}
for (int i = 1; i <= n; i++) a[i] = c[i];
}
for (int i = 1; i <= n; i++) {
printf("%d%s", c[i], i < n ? " " : "\n");
}
}
return 0;
}