题目:(时间限制:4000MS)
给你n个整数,请按从大到小的顺序输出其中前m大的数。
Input
每组测试数据有两行,第一行有两个数 n, m ( 0 < n, m < 4000000 );第二行包含n个各不相同,且都处于区间[-2000000,2000000]的整数。
Output
对每组测试数据按从大到小的顺序输出前m大的数。
Sample Input
5 3
3 -35 92 213 -644
Sample Output
213 92 3
做法一::哈希
哈希算法是一种以空间换取时间的算法。
本题的哈希思路:输入一个数字x的时候,对应a[2000000+x]这个位置,标记a[2000000+x]=1,输出时逐个检查a[i],若等于1则输出,输出前m个。代码如下:
#include<bits/stdc++.h>
using namespace std;
const int MAX=4000001;
int a[MAX];
int main()
{
int n,m,x;
while(~scanf("%d%d",&n,&m))
{
memset(a,0,sizeof(a));
for(int i=0;i<n;i++){
scanf("%d",&x);
a[2000000+x]=1;
}
for(int j=MAX;m>0;j--){
if(a[j]){
if(m>1)
printf("%d ",j-2000000);
else
printf("%d\n",j-2000000);
m--;
}
}
}
return 0;
}
该做法在每次输入时就把输入的数按照哈希直接插入到对应的位置,n个数输入完毕也就相当于排好了序。总的时间复杂度:O(n)。
做法二: 用排序函数,sort(复杂度:nlog2(n) )会超时,用partial_sort.
#include<bits/stdc++.h>
using namespace std;
int a[1000005];
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
partial_sort(a,a+m,a+n,greater<int>());
for(int i=0;i<m-1;i++){
printf("%d ",a[i]);
}
printf("%d\n",a[m-1]);
}
return 0;
}
做法三: 推排序
(推排序待学习之后再补充)