知识点:堆
这个很明显就是进阶指南上面的那种类型的题目,是3个序列合并的,这个数据范围很小,可以直接暴力,但是那样的时间复杂度就太高了,用堆优化和数学归纳法可以很快的做出来,就是先合并1和2序列,然后拿着合并好的序列去和3序列合并,这里需要注意的地方就是1和2合并完序列的长度是多少,这个点注意一下这个题就没什么了
#include <bits/stdc++.h>
using namespace std;
const int N = 3005;
struct node {
int x, y;
long long v;
node() {}
node(int a, int b, long long c): x(a), y(b), v(c) {}
bool operator < (const node &a) const {
return v < a.v;
}
};
long long a[N], b[N], c[N];
bool cmp(long long a, long long b) {
return a > b;
}
int main() {
int n1, n2, n3, k;
cin >> n1 >> n2 >> n3 >> k;
priority_queue<node> q;
for (int i = 1; i <= n1; i++) cin >> a[i];
for (int i = 1; i <= n2; i++) cin >> b[i];
sort(a + 1, a + n1 + 1, cmp);
sort(b + 1, b + n2 + 1, cmp);
for (int i = 1; i <= n1; i++) {
q.push(node(i, 1, a[i] + b[1]));
}
for (int i = 1; i <= min(n1 * n2, k); i++) {
node now = q.top(); q.pop();
c[i] = now.v;
if (now.y == n2) continue;
q.push(node(now.x, now.y + 1, a[now.x] + b[now.y + 1]));
}
for (int i = 1; i <= n3; i++) cin >> b[i];
sort(b + 1, b + n3 + 1, cmp);
for (int i = 1; i <= min(n1 * n2, k); i++) {
q.push(node(i, 1, c[i] + b[1]));
}
for (int i = 1; i <= k; i++) {
node now = q.top(); q.pop();
cout << now.v << '\n';
if (now.y == n3) continue;
q.push(node(now.x, now.y + 1, c[now.x] + b[now.y + 1]));
}
return 0;
}