zoukankan      html  css  js  c++  java
  • Codevs 1245 最小的N个和

    1245 最小的N个和

     

     时间限制: 1 s
     空间限制: 128000 KB
     题目等级 : 钻石 Diamond
     
     
    题目描述 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[2]时,b[i]加上a[2]一定不如加上a[1]优,所以一定已经选过b[i],a[1],题目要求输出前n个,也就是在确定了a[i]时在b[]中最多选n/i个数 
    */
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define maxn 200010
    int a[maxn],b[maxn],c[maxn*100],n,cnt;
    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]);
        sort(a+1,a+n+1);sort(b+1,b+n+1);
        for(int i=1;i<=n;i++)
            for(int j=1;i*j<=n;j++)
                c[++cnt]=a[i]+b[j];
        sort(c+1,c+cnt+1);
        for(int i=1;i<=n;i++)printf("%d ",c[i]);
    }
    方法一 (排除)
    #include <iostream>
    #include <algorithm>
    #include<cstdio>
    #define M 100001
    using namespace std;
    struct node
    {
        int s,aa,bb;
    };node tree[(M<<1)+1];
    int a[M],b[M];
    int n,len,kk;
    int main()
    {
        cin>>n;
        for(int i=1;i<=n;i++)cin>>a[i];
        for(int i=1;i<=n;i++)cin>>b[i];
        sort(a+1,a+n+1);
        sort(b+1,b+n+1);
        for(int i=1;i<=n;i++)
        {
            tree[i].aa=i;
            tree[i].bb=1;
            tree[i].s=a[i]+b[1];
        }
        len=n;
        while(1)
        {
            cout<<tree[1].s<<" ";
            kk++;
            tree[1].bb++;
            tree[1].s=a[tree[1].aa]+b[tree[1].bb];
            if(tree[1].bb>n)tree[1].s=1e9;
            int q=1;
            while(1)
            {
                int q1=q<<1,q2=q1+1;
                if(q1>len)break;
                if(q2<=len&&tree[q2].s<tree[q1].s)q1=q2;
                if(tree[q].s<=tree[q1].s)break;
                    else swap(tree[q],tree[q1]);
                q=q1;
            }
            if(kk==n)break;
        }
        return 0;
    }
    方法二 堆排
  • 相关阅读:
    不可或缺 Windows Native (15)
    不可或缺 Windows Native (14)
    不可或缺 Windows Native (13)
    不可或缺 Windows Native (12)
    不可或缺 Windows Native (11)
    不可或缺 Windows Native (10)
    不可或缺 Windows Native (9)
    不可或缺 Windows Native (8)
    不可或缺 Windows Native (7)
    不可或缺 Windows Native (6)
  • 原文地址:https://www.cnblogs.com/thmyl/p/7605883.html
Copyright © 2011-2022 走看看