[Hash应用问题] 例3.2 给出n个整数,按从大到小的顺序输出前m大的数

题目描述:
给出n个整数,请按从大到小的顺序输出前m大的数。
输入:
每组测试数据又两行,第一行有两个数n,m(0<n,m<1000000),第二行包含n个各不相同,且都处于区间[-500000,500000]的整数。
输出:
对每组测试数据按从大到小的顺序输出前m大的数。
样例输入:
5 3
3 -35 92 213 -644
样例输出:
213 92 3

解题思路: 本题有人可能会想到先排序然后再输出前m个大的数,该方法在数据量大的时候,容易发生超时,当然也有建立最大堆的方法,本题采用Hash方法,利用一个数组标记所出现的数字,输入结束后从后往前遍历数组,输出标记过的m个数, 输出即为降序的前m大的数。

#include<bits/stdc++.h>
#define OFFSET 500000 //偏移量,用于补偿实际数字与数组下标之间的偏移 
using namespace std; 
int Hash[1000001]; //Hash数组,记录每个数字是否出现,不出现为0,出现后被标记成1 

int main()
{
	int n, m;
	while(scanf("%d%d", &n, &m)!=EOF){
		for(int i=-500000; i<=500000; i++){
			Hash[i+OFFSET] = 0;
		}
		for(int i=1; i<=n; i++){
			int x;
			cin >> x;
			Hash[x+OFFSET] = 1;//凡是出现过的数字,该数组元素均被设置成1 
		}
		for(int i = 500000; i>=-500000; i--){//输出前m个数 
			if(Hash[i+OFFSET]==1){//若该数字在输入中出现 
				cout << i;//输出该数字 
				m--;//输出一个数字后,m--,直至m变为0 
				if(m>0) cout << " ";//注意格式,若m个数未被输出完毕,在输出数字后紧跟一个空格 
				else{
					cout << endl;
					break;
					//若m个数字已经被输出完毕,则在输出的数字后面紧跟一个换行,并跳出遍历循环 
				} 
			}
		}
	}
	return 0;
}

结束


猜你喜欢

转载自blog.csdn.net/zdx1996/article/details/86582671