题目描述
有两个长度都为N的序列A和B,在A和B中各取一个数相加可以得到N2个和,求这N2个和中最小的N个。
输入
第一行一个正整数N(1 <= N <= 100000)。
第二行N个整数Ai,满足Ai <= Ai+1且Ai <= 109
第三行N个整数Bi,满足Bi <= Bi+1且Bi <= 109
输出
输出仅有一行,包含N个整数,从小到大输出这N个最小的和,相邻数字之间用空格隔开。
样例输入
3
2 6 6
1 4 8
样例输出
3 6 7
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn = 100010;
int a[maxn], b[maxn];
LL heap[maxn];
int num, n;
void upAdjust(int low, int high)
{
int i = high, j = i / 2;
while (j >= low)
{
if (heap[i] > heap[j])
{
swap(heap[i], heap[j]);
i = j;
j = i / 2;
}
else break;
}
}
void downAdjust(int low, int high)
{
int i = low, j = i * 2;
while (j <= high)
{
if (j + 1 <= high && heap[j + 1] > heap[j])
{
j = j + 1;
}
if (heap[j] > heap[i])
{
swap(heap[j], heap[i]);
i = j;
j = i * 2;
}
else break;
}
}
void insert(int x)
{
heap[++num] = x;
upAdjust(1, num);
}
void del()
{
heap[1] = heap[num--];
downAdjust(1, num);
}
void heapSort()
{
for (int i = num; i > 1; i--)
{
swap(heap[i], heap[1]);
downAdjust(1, i - 1);
}
}
int main()
{
while (scanf("%d", &n) != EOF)
{
num = 0;
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++) insert(a[1] + b[i]);
for (int i = 2; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
int temp = a[i] + b[j];
if (temp < heap[1])
{
del();
insert(temp);
}
else break;
}
}
heapSort();
for (int i = 1; i <=n ; i++)
printf("%d ", heap[i]);
printf("\n");
}
return 0;
}