1431:Sort

83 阅读1分钟
  • 题目描述:

    给你n个整数,请你按从大到小的顺序输出其中前m大的数。

  • 输入:

    每组测试数据有两行,第一行有两个数n,m(0

    #include <stdio.h>
    #include <stdlib.h>
    #include <iostream>
    #include <algorithm>

    using namespace std;

    bool cmp(int x,int y){
    return x>y;
    }

    int main()
    {
        int n,m;
        int buf[1000001];
        while(scanf("%d %d",&n,&m)!=EOF){
            for(int i=0;i<n;i++){
                scanf("%d",&buf[i]);
            }
            sort(buf,buf+n,cmp);
            for(int i=0;i<m;i++){
                printf("%d ",buf[i]);
            }
        }
        return 0;
    }
    /*
    5 3
    3 -35 92 213 -644
    */

用上面的简单排序的方法做可以得出结果,但时间复杂度会达到千万数量级,无法在一秒内完成,那么用Hash数组的方式怎么来实现呢?
本题中要求输入的数据是-500000~500000之间,会有负数的出现,而数组的下标从0开始,这就需要我们将<0范围的做一个处理,加上一个偏移值,使其转化到[0,1000000]之间,这样我们就可以使用Hash数组了。
AC代码:

    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>

    using namespace std;

    #define OFFSET 500000 //偏移量,进行负坐标的转化,便于处理
    int Hash[1000001]; //建立一个Hash数组储存数据

    int main()
    {
        int n,m;
        while(scanf("%d%d",&n,&m)!=EOF){
            //初始化Hash数组
            for(int i=-500000;i<=500000;i++){
                Hash[i+OFFSET]=0;
                //初始化为0,范围内的每一个数字均未出现过
            }

            //输入数据
            for(int i=1;i<=n;i++){
                int x;
                scanf("%d",&x);
                Hash[x+OFFSET]=1;
                //出现的数字标为1,未出现的仍然为0
            }

            //统计
            for(int i=500000;i>=-500000;i--){
                if(Hash[i+OFFSET]==1){
                    printf("%d",i);
                    m--;
                    //若未输出完则后跟空格,否则换行
                    if(m!=0){
                        printf(" ");
                    }else{
                        printf("\n");
                        break;
                    }
                }
            }
        }
        return 0;
    }
    /*
    5 3
    3 -35 92 213 -644
    */