w5 P1631 序列合并

发布时间 2023-04-12 18:21:42作者: RUI_26

 

主要思路:由于题干中说明给出的两个序列是单调不降的,所以不需要再对序列进行一个排序。这里其实有一点贪心的意思但不完全是贪心算法。首先把两个序列分别放入两个数组,然后进行各个元素和的遍历。构建一个优先序列pq,优先序列会对里面的元素自动降序排列,每次遍历都判断和是否小于pq 内的最大元素,即pq.top(),是则扔出top,放入当前的和。

以样例为例:

a:a1=2 a2=6 a3=6

b:b1=1 b2=4 b3=8

若pq大小!=N,则先把元素放入pq,pq:10 6 3,分别对应a1+b1 a1+b2 a1+b3

a2+b1=7<10,扔出10,放入7,pq:7 6 3

a2+b2=10>7,继续遍历

a2+b3=14>7,继续遍历

a3+b1=7==7,继续遍历

a3+b2=10>7,继续遍历

a3+b3=14>7,已全部遍历完,倒序输出结果

 

代码如下:

#include<iostream>
#include<queue>
using namespace std;
int N,a[100005],b[100005],cnt;
priority_queue<int> pq;
int main()
{
  cin>>N;
  for(int i=0;i<N;++i) cin>>a[i];
  for(int i=0;i<N;++i) cin>>b[i];
  for(int i=0;i<N;++i){
    for(int j=0;j<N;++j){
      if(pq.size()<N){ //若pq大小!=N时输入数据
      pq.push(a[i]+b[j]);
      }
      else{ //pq大小==N时,判断当前数字,比top大则继续循环,比top小则放入pq
        if(a[i]+b[j]<pq.top()){
        pq.pop();
        pq.push(a[i]+b[j]);
        }
        else break;
      }
    }
  }
  int ans[N],i=N-1;
  while(!pq.empty()){ //倒叙存放结果
    ans[i]=pq.top();
    pq.pop();
    i--;
  }
  for(int i=0;i<N;++i) cout<<ans[i]<<" "; //输出结果
  cout<<endl;
  return 0;
}