洛谷题目连接:序列合并
题目描述
有两个长度都是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; }