-
题目描述:
给你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
*/