zoukankan      html  css  js  c++  java
  • 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

    此题需要注意的是必须先对两个输入数组进行排序,乱序的数据量N^2太大,数组存不下。然后就是时间复杂度的问题,必须过滤掉一部分数据。对于有序数组a[i],b[j].i*j-1>N的数据是无效的数据。因为已经存在了N个更小的数据。例如当N = 100的时候,i=5,j=20时,(i=1,2,3,4且j<=20) 和( i=5且j<20)的数据一定比a[5]+b[20]小,所以已经存在了100个很小的数据了就不需要比较后续的数据了。完全可以忽略。至于i*j-1的-1是因为i,j这组数据并没有算进去。

    因为需要联系堆排序,就使用了堆排序做题:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define MAX_NUM 100005
    int heapArr[MAX_NUM*100];
    int heapCount = 1;
    int a[MAX_NUM];
    int b[MAX_NUM];
    void insert(int a);
    int pop();
    int main(){
        int N;
        cin >> N;
        for (int i = 0; i < N; i++){
            cin >> a[i];
        }
        for (int i = 0; i < N; i++){
            cin >> b[i];
        }
        sort(a, a + N);
        sort(b, b + N);
        for (int i = 0; i < N; i++){
            for (int j = 0; j < N; j++){
                if (i*j - 1 > N) break;
                insert(a[i] + b[j]);
            }
        }
        for (int i = 0; i < N; i++){
            cout << pop() << " ";
        }
        cout << endl;
        return 0;
    }
    void insert(int a){
        heapArr[heapCount] = a;
        int i = heapCount;
        int j = i / 2;
        while (j > 0){
            if (heapArr[i] < heapArr[j]){
                int temp = heapArr[i];
                heapArr[i] = heapArr[j];
                heapArr[j] = temp;
                i = j;
                j = i / 2;
            }
            else{
                break;
            }
        }
        //if (heapCount<MAX_NUM*2) //想当然的进行了数据忽略,然后发现忽略是错误的,对于堆排序本身,叶子节点的数并不代表是很大的数,可能叶子节点的数小于根节点的另一个孩子(次节点的祖先的兄弟节点)。
            heapCount++;
    }
    int pop(){
        int ans = heapArr[1];
        heapCount--;
        heapArr[1] = heapArr[heapCount];
        int i = 1;
        int j = i * 2;
        int k = j + 1;
        while (j < heapCount){
            if (k < heapCount){
                if (heapArr[j] > heapArr[k]){
                    if (heapArr[i] > heapArr[k]){
                        int temp = heapArr[i];
                        heapArr[i] = heapArr[k];
                        heapArr[k] = temp;
                        i = k;
                        j = i * 2;
                        k = j + 1;
                    }
                    else 
                        break;
    
                }
                else{
                    if (heapArr[i] > heapArr[j]){
                        int temp = heapArr[i];
                        heapArr[i] = heapArr[j];
                        heapArr[j] = temp;
                        i = j;
                        j = i * 2;
                        k = j + 1;
                    }
                    else 
                        break;
                }
            }
            else{
                if (heapArr[i] > heapArr[j]){
                    int temp = heapArr[i];
                    heapArr[i] = heapArr[j];
                    heapArr[j] = temp;
                    i = j;
                    j = i * 2;
                    k = j + 1;
                }
                else{
                    break;
                }
            }
        }
        return ans;
    }

    犯了一个错误,记录一下

       //if (heapCount<MAX_NUM*2) //想当然的进行了数据忽略,然后发现忽略是错误的,对于堆排序本身,叶子节点的数并不代表是很大的数,可能叶子节点的数小于根节点的另一个孩子(次节点的祖先的兄弟节点)。
  • 相关阅读:
    mysql truncate
    蠕虫复制
    mysql 一对多,多对多
    php实现文件下载
    JetBrains PhpStorm 整个项目中查找一个词语
    vim
    程序员减少代码BUG的7种方法,拒绝编程5分钟,查代码2小时!
    创建你的第一个Composer/Packagist包
    Elasticsearch
    Laravel 实践之路: 数据库迁移与数据填充
  • 原文地址:https://www.cnblogs.com/weifengxiyu/p/8473346.html
Copyright © 2011-2022 走看看