题目描述
有两个长度都是N的序列A和B,在A和B中各取一个数相加可以得到N^2个和,求这N^2个和中最小的N个。
输入
第一行一个正整数N;
第二行N个整数Ai,满足Ai<=Ai+1且Ai<=10^9;
第三行N个整数Bi, 满足Bi<=Bi+1且Bi<=10^9.
输出
仅一行,包含N个整数,从小到大输出这N个最小的和,相邻数字之间用空格隔开。
样例输入
3
2 6 6
1 4 8
样例输出
3 6 7
提示
对于50%的数据中,满足1<=N<=1000;
对于100%的数据中,满足1<=N<=100000。
解:
可以从题目中得出以下信息:
A1+B1<=A1+B2<=A1+B3...<=A1+Bn
A2+B1<=A2+B2<=A2+B3...<=A2+Bn
...
An+B1<=An+B2<=An+B3...<=An+Bn
所以计算的时候,先算第一列的最小值,然后模拟,一直到第n列,使用优先级队列
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int M = 100000 + 10; struct Item { ll s,b; Item(int s, int b):s(s),b(b) {}; bool operator < (const Item& rhs) const{ return s > rhs.s; } }; ll a[M],b[M],n; priority_queue<Item> q; int main() { 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++) q.push(Item(b[1]+a[i],1)); for(int i = 0; i < n; i++) { cout<<q.top().s<<" "; Item item = q.top(); q.pop(); int index = item.b; if(index+1 <= n) q.push(Item(item.s-b[index]+b[index+1],index+1)); } return 0; }
Okkkkk,hahaha