題目描述
有兩個長度都爲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
提示
建議用最小堆實現。
起初我用書上寫的堆的方法來實現,。。。。後來沒寫出來。。
百度發現可以用優先隊列直接實現堆操作。
來自一個大神的代碼:
https://blog.csdn.net/a845717607/article/details/81636002
#include<stdio.h>
#include<algorithm>
#include<queue>
using namespace std;
int heap1[100001];
int heap2[100001];
int n;
int main()
{
while(scanf("%d",&n)!=EOF)
{
priority_queue<int> q;//優先隊列實現堆
for(int i=1; i<=n; i++)
scanf("%d", &heap1[i]);
for(int i=1; i<=n; i++)
scanf("%d", &heap2[i]);
for(int i=1; i<=n; i++)
{
q.push(heap1[1]+heap2[i]);
}
for(int i=2; i<=n; i++)
{
for(int j=1; j<=n; j++)
{
if(heap1[i] + heap2[j] < q.top())//隊尾元素
{
q.pop();
q.push(heap1[i]+heap2[j]);
}
else
break;
}
}
int ans[100010];
for(int i=n-1; i>=0; i--)
{
ans[i] = q.top();
q.pop();
}
for(int i=0; i<n; i++)
{
printf("%d",ans[i]);
if(i!=n-1)
printf(" ");
}
printf("\n");
}
return 0;
}