zoukankan      html  css  js  c++  java
  • Problem B: 序列合并

    Description

    有两个长度都为N的序列A和B,在A和B中各取一个数相加可以得到N2个和,求这N2个和中最小的N个。

    Input

    第一行一个正整数N(1 <= N <= 100000)。
    第二行N个整数Ai,满足Ai <= Ai+1且Ai <= 109
    第三行N个整数Bi,满足Bi <= Bi+1且Bi <= 109

    Output

    输出仅有一行,包含N个整数,从小到大输出这N个最小的和,相邻数字之间用空格隔开。

    Sample Input

    3
    2 6 6
    1 4 8

    Sample Output

    3 6 7

    HINT

    建议用最小堆实现。

    题目链接:序列合并

    参考链接:最小的N个和(优先队列)

    最终AC代码如下:

    #include<bits/stdc++.h>
    using namespace std;
    const int MAX=1e5+2;
    struct Node{
        int index, sum;
        bool operator < (const Node &t) const{
            return sum > t.sum; //优先队列表示按sum的大小排列 
        }
    };
    int main(){
        int i, n, a[MAX], b[MAX];
        Node temp, now;
        priority_queue<Node> q;
        while(cin >> n){
            for(i=0; i<n; i++) scanf("%d", &a[i]);
            for(i=0; i<n; i++){
                scanf("%d", &b[i]);
                temp.index = 0;
                temp.sum = b[i] + a[temp.index];  //index表示a[]中的第几个数字 
                q.push(temp);
            }
            for(i=0; i<n; i++){
                now = q.top();
                q.pop();
                if(now.index+1 < n){
                    temp.index = now.index + 1;
                    temp.sum = now.sum - a[now.index] + a[temp.index];
                    q.push(temp);
                }
                printf("%d%c", now.sum, i==n-1?'
    ':' ');
            }
        }  
        return 0;
    }

    总结:一开始看见提示,用最小堆做,但是没想到具体的思路~自认为本题的难点在于,虽然两组数据都是分别单调不减的,但是要求和最小(分别从两个序列中取数,每个数可以重复利用)的前N个数,于是就有很多不确定性了。如果数据量不是很大的情况,也许可以暴力,但是此题显然不行。

    参考别人的思路后,发现可以用优先队列做(平时优先队列用得少,真的没想起这思路)。自己对这种思路的理解大致如下:

    首先,取a[]数组中的最小元素,也就是a[0],分别加上b[i](0<=i<n),并放入优先队列中。那么可以确定,此时优先队列队首的元素,也即a[0]+b[0]的值就是最小的,可以输出,并将a[1]+b[0]输入优先队列,依次类推,直到输出了n个数为止。

    上述过程,逻辑看似简单,但是要注意几点:

    1、优先队列存放的元素是结构体变量。定义结构体的目的,结构体内sum变量存放两个数之和,index记录a[]的下标,从而为后面每次更新sum埋伏笔。

    2、由于优先队列存放的元素是结构体变量,因此需要自定义比较的容器~然而这种定义方式着实不易理解,暂且先记住。

    3、入队前对index的范围的判断,在此题可以省略(试了一下,没啥影响)。

  • 相关阅读:
    Windows下安装redis,并与PHP使用
    php中的一些小细节(1)
    MIME类型
    Oracle与SQL Server事务处理的比较
    php+memcached缓存技术实例
    B-树
    平衡二叉树(AVL)
    树--二叉查找树(二叉排序树)
    八种常见的排序算法
    反转一个值中的最后n位
  • 原文地址:https://www.cnblogs.com/heyour/p/12711821.html
Copyright © 2011-2022 走看看