题目描述 Description
有两个长度为 N 的序列 A 和 B,在 A 和 B 中各任取一个数可以得到 N^2 个和,求这N^2 个和中最小的 N个。
输入描述 Input Description
第一行输入一个正整数N;第二行N个整数Ai 且Ai≤10^9;第三行N个整数Bi,
且Bi≤10^9
输出描述 Output Description
输出仅一行,包含 n 个整数,从小到大输出这 N个最小的和,相邻数字之间用
空格隔开。
样例输入 Sample Input
5
1 3 2 4 5
6 3 4 1 7
样例输出 Sample Output
2 3 4 4 5
数据范围及提示 Data Size & Hint
【数据规模】 对于 100%的数据,满足 1≤N≤100000。
思路:n^2枚举 妥妥的超时
我们或许可以二分 但是还是需要找前n个数
所以 我们可以 先用一个priority_queue 记录n个值
初始化 把a[1]+b[i] 丢进一个堆中
每次弹出最小的值 因为是最小的a+b中的任意一个元素 所以 我们把a[1] 换成a[2]
用来更新 堆中的元素 这一定是合法的
直到找到n个元素为止
1 #include <queue> 2 #include <cctype> 3 #include <cstdio> 4 #include <algorithm> 5 6 using namespace std; 7 8 const int MAXN=200010; 9 10 int n,sum,Head_a,Head_b; 11 12 int a[MAXN],b[MAXN],ans[MAXN]; 13 14 pair<int,int> Pr; 15 16 struct node { 17 int first,second; 18 node() {} 19 node(int first,int second):first(first),second(second) {} 20 friend bool operator < (node a,node b) { 21 return a.first>b.first; 22 } 23 }; 24 node pr; 25 26 std::priority_queue<node> q; 27 28 inline void read(int&x) { 29 int f=1;register char c=getchar(); 30 for(x=0;!isdigit(c);c=='-'&&(f=-1),c=getchar()); 31 for(;isdigit(c);x=x*10+c-48,c=getchar()); 32 x=x*f; 33 } 34 35 int hh() { 36 freopen("hahaha.in","r",stdin); 37 freopen("hahaha.out","w",stdout); 38 read(n); 39 for(int i=1;i<=n;++i) read(a[i]); 40 std::sort(a+1,a+1+n); 41 for(int i=1;i<=n;++i) { 42 read(b[i]); 43 q.push(node(b[i]+a[1],1)); 44 } 45 sum=0; 46 Head_a=Head_b=1; 47 while(sum<=n) { 48 pr=q.top(); 49 q.pop(); 50 ans[++sum]=pr.first; 51 pr.first=pr.first-a[pr.second]+a[++pr.second]; 52 q.push(pr); 53 } 54 for(int i=1;i<=n;++i) printf("%d\n",ans[i]); 55 fclose(stdin); 56 fclose(stdout); 57 return 0; 58 } 59 60 int sb=hh(); 61 int main(int argc,char**argv) {;}