题意
给你两个长度都为 n n n 的整数序列 a i a_i ai 和 b i b_i bi ,问你求出前 n n n小的 a i + b j a_i+b_j ai+bj
解题方法
我们一看到小,就首先想到把两个数组都从小到大排序一遍,然后我们发现了
n
n
n 个如下的不等式
a
1
+
b
1
≤
a
1
+
b
2
≤
a
1
+
b
3
≤
.
.
.
≤
a
1
+
b
n
a
2
+
b
1
≤
a
2
+
b
2
≤
a
2
+
b
3
≤
.
.
.
≤
a
2
+
b
n
.
.
.
a
n
+
b
1
≤
a
n
+
b
2
≤
a
n
+
b
3
≤
.
.
.
≤
a
n
+
b
n
a_1+b_1\leq a_1+b_2\leq a_1+b_3 \leq ...\leq a_1+b_n\\a_2+b_1\leq a_2+b_2\leq a_2+b_3\leq ...\leq a_2+b_n\\...\\a_n+b_1\leq a_n+b_2\leq a_n+b_3\leq ...\leq a_n+b_n
a1+b1≤a1+b2≤a1+b3≤...≤a1+bna2+b1≤a2+b2≤a2+b3≤...≤a2+bn...an+b1≤an+b2≤an+b3≤...≤an+bn
然后我们就每次取出每个不等式的最小值然后丢进一个堆里面,每次取出堆顶然后把那个属于的不等式的最小值再扔回去。
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
int a[100005],b[100005];
priority_queue<pair<int,int> >q;
int top[100005];
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
scanf("%d",&b[i]);
sort(a+1,a+n+1);
sort(b+1,b+n+1);
for(int i=1;i<=n;i++)
q.push(make_pair(-(a[i]+b[1]),i)),top[i]=1;
for(int i=1;i<=n;i++)
{
int x,y;
x=q.top().first;
cout<<-x<<' ';
y=q.top().second;
q.pop();
top[y]++;
q.push(make_pair(-(a[y]+b[top[y]]),y));
}
return 0;
}