【算法筆記第9.7節-堆排序】問題 B: 序列合併

題目描述

有兩個長度都爲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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章