wikioi 1245最小N個和
阿新 • • 發佈:2019-02-19
題目描述 Description
資料範圍及提示 Data Size & Hint
有兩個長度為 N 的序列 A 和 B,在 A 和 B 中各任取一個數可以得到 N^2 個和,求這N^2 個和中最小的 N個。
輸入描述 Input Description第一行輸入一個正整數N;第二行N個整數Ai 且Ai≤10^9;第三行N個整數Bi,
且Bi≤10^9
輸出僅一行,包含 n 個整數,從小到大輸出這 N個最小的和,相鄰數字之間用
空格隔開。
5
1 3 2 4 5
6 3 4 1 7
2 3 4 4 5
【資料規模】 對於 100%的資料,滿足 1≤N≤100000。
題解:將兩個序列按從小到大排序(實際資料已經有序),對於A[i]和B[j],a[i]+b[j]<a[i]+b[j+1]必然成立。
於是我們建一個大根堆,儲存最小的N個和。先將A[1]和B的和放入堆中,之後的A[I]和B[J]的和每次與堆頂比較,大於則直接break,小於則置換堆頂即可。輸出時逆序輸出堆中元素
#include<queue> #include<cstdio> #include<iostream> #define MAXN 1000000 using namespace std; priority_queue<int> heap; int n; int a[MAXN+5],b[MAXN+5],ans[MAXN+5]; int main() { 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]); for (int i=1;i<=n;i++) heap.push(a[1]+b[i]); for (int i=2;i<=n;i++) { for (int j=1;j<=n;j++) { int now=a[i]+b[j]; if (now<heap.top()) { heap.pop(); heap.push(now); } else break; } } for (int i=1;i<=n;i++) { ans[i]=heap.top(); heap.pop(); } for (int i=n;i>=1;i--) printf("%d ",ans[i]); return 0; }