[洛谷P1631] 序列合併

洛谷題目連接:序列合併

題目描述

有兩個長度都是N的序列A和B,在A和B中各取一個數相加能夠獲得 N2N^2N2 個和,求這 N2N^2N2 個和中最小的N個。ios

輸入輸出格式

輸入格式:c++

第一行一個正整數N;spa

第二行N個整數 AiA_iAi​ , 知足 Ai≤Ai+1A_i\le A_{i+1}Ai​≤Ai+1​ 且 Ai≤109A_i\le 10^9Ai​≤109 ;code

第三行N個整數 BiB_iBi​ , 知足 Bi≤Bi+1B_i\le B_{i+1}Bi​≤Bi+1​ 且 Bi≤109B_i\le 10^9Bi​≤109 .ci

【數據規模】get

對於50%的數據中,知足1<=N<=1000;it

對於100%的數據中,知足1<=N<=100000。io

輸出格式:class

輸出僅一行,包含N個整數,從小到大輸出這N個最小的和,相鄰數字之間用空格隔開。queue

輸入輸出樣例

輸入樣例#1:

3 2 6 6 1 4 8

輸出樣例#1:

3 6 7 </br>

一句話題意: 兩個長度爲$n$的單調遞增的序列能夠組成$n^2$個組合,問這些組合中最大的前$k$個. </br>

題解: 首先看一下下面這張表: A[1]+B[1] <= A[1]+B[2] <= … <= A[1]+B[N]

A[2]+B[1] <= A[2]+B[2] <= … <= A[2]+B[N]

……

A[N]+B[1] <= A[N]+B[2] <= … <= A[N]+B[N] 顯然,同一列每一行都比下面一行的值要大. 因此,咱們能夠先將$A_1$~$A_n$與$B_1$的值都加入堆中,每次取出了堆中的最大值,就把它所在的行的下一個加入堆中,能夠保證這樣是單調的.

#include<bits/stdc++.h>
using namespace std;
const int N=100000+5;

int n, a[N], b[N], ans[N];

struct number{
    int id1, id2, val;
    bool operator < (const number &a) const{
	    return val > a.val;
    }
};

priority_queue <number> h;

int main(){
    ios::sync_with_stdio(false);
    cin >> n;
    for(int i=1;i<=n;i++) cin >> a[i];
    for(int i=1;i<=n;i++) cin >> b[i];
    for(int i=1;i<=n;i++) h.push((number){ i, 1, a[i]+b[1] });
    for(int i=1;i<=n;i++){
	    number top = h.top(); h.pop();
	    ans[i] = top.val;
	    h.push((number){ top.id1, top.id2+1, a[top.id1]+b[top.id2+1] });
    }
    for(int i=1;i<=n;i++) cout << ans[i] << ' '; cout << endl;
    return 0;
}
相關文章
相關標籤/搜索