codevs 1245 最小的N个和

题目描述 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
",ans[i]);
55     fclose(stdin);
56     fclose(stdout);
57     return 0;
58 }
59 
60 int sb=hh();
61 int main(int argc,char**argv) {;}
代码
原文地址:https://www.cnblogs.com/whistle13326/p/7605903.html