wikioi 1245最小N个和

来源:互联网 发布:淘宝十大男模特 编辑:程序博客网 时间:2024/05/17 22:59
题目描述 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。


题解:将两个序列按从小到大排序(实际数据已经有序),对于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;  }  


0 0
原创粉丝点击