zoukankan      html  css  js  c++  java
  • P1631 序列合并

    首先,把A和B两个序列分别从小到大排序,变成两个有序队列。这样,从A和B中各任取一个数相加得到N2个和,可以把这些和看成形成了n个有序表/队列:

    A[1]+B[1] <= A[1]+B[2] <= … <= A[1]+B[N]

    A[2]+B[1] <= A[2]+B[2] <= … <= A[2]+B[N]

    ……

    A[N]+B[1] <= A[N]+B[2] <= … <= A[N]+B[N]

    接下来,就相当于要将这N个有序队列进行合并排序:

    首先,将这N个队列中的第一个元素放入一个堆中;

    然后;每次取出堆中的最小值。若这个最小值来自于第k个队列,那么,就将第k个队列的下一个元素放入堆中。

    假设我们当前取出的是a[i]+b[j],那么我们下一次取的就是a[i]+b[j+1]或a[i+1]+b[j]。我们先把b序列中所有数与a[1]的和放入优先队列,这样就满足了a[i]+b[j+1]的情况。所以重点就是处理a[i+1]+b[j],每次把取出b[j]对应的取到a数组中的位置往后移一个加入优先队列即可。

    const int N=1e5+10;
    struct Node
    {
        int i,j;
        int sum;
        bool operator>(const Node &W) const
        {
            return sum > W.sum;
        }
    };
    int a[N],b[N];
    int n;
    
    int main()
    {
        cin>>n;
    
        for(int i=0;i<n;i++) cin>>a[i];
    
        priority_queue<Node,vector<Node>,greater<Node>> heap;
        for(int i=0;i<n;i++)
        {
            cin>>b[i];
            heap.push({i,0,a[i]+b[0]});
        }
    
        for(int i=0;i<n;i++)
        {
            Node t=heap.top();
            heap.pop();
    
            cout<<t.sum<<' ';
            heap.push({t.i,t.j+1,a[t.i]+b[t.j+1]});
        }
        cout<<endl;
        //system("pause");
        return 0;
    }
    
  • 相关阅读:
    财务自由之路-我用Airtest刷抖音致富
    Python基础-背单词游戏
    别人是在谈薪酬,而你是在自残
    不写一行代码,使用Airtest完成自动化测试
    精致的JavaScript代码
    浅谈排序二叉树
    JavaScript 生产者消费者模型
    IDEA 激活码全家桶 webStorm亲测可用【更新日期2020.3.30】
    Cocos-JS HTTP网络请求
    初始OpenGL
  • 原文地址:https://www.cnblogs.com/fxh0707/p/14454052.html
Copyright © 2011-2022 走看看