(三)王道机试指南___Hash的应用

算例1

  • 题目描述

  • 解题思路

①方法一:用数组将输入数据存储,遍历查找比较统计

②方法二:因输入的分数控制在100以内且为整数,即种类有限,共101种可能,因此利用hash数组对这101种可能分别计数即可

  • 解题代码

#include <stdio.h>
int main() {
	int n;
	while (scanf("%d", &n) != EOF && n != 0) { //输入判断增加对n是否等于零进行判断
			int Hash[101] = { 0 }; //建立一个初始为0的Hash数组用来记录各种分数出现的次数
			for (int i = 1; i <= n;i++) {
				int x;
				scanf("%d", &x);
				Hash[x] ++; //统计分数出现次数
			}
		int x;
		scanf("%d", &x);
		printf("%d\n", Hash[x]); // 得到需要查询的目标分数后,只需简单的查询我们统计的数量即可
	}
	return 0;
}
  • 注意点

①如此简洁明了啊,事半功倍!

算例2

  • 题目描述

  • 解题思路

①这里要思考复杂度问题,排序数量比较庞大1000000,即使使用快排(O(nlogn)),时间复杂度会达到千万数量级,超出时间限制

②此题的输入数据种类也是有限的,所以利用hash数组求解,只需统计一遍+遍历查找一遍,时间复杂度在百万数量级,满足时间要求

  • 解题代码

#include <stdio.h>
#define OFFSET 500000 //偏移量,用于补偿实际数字与数组下标之间偏移
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;
			scanf("%d", &x);
			Hash[x + OFFSET] = 1; //凡是出现过的数字,该数组元素均被设置成1
		}
		for (int i = 500000; i >= -500000; i--) { //输出前m个数
			if (Hash[i + OFFSET] == 1) { //若该数字在输入中出现
				printf("%d", i); //输出该数字
				m--; //输出一个数字后,m减一,直至m变为0
				if (m != 0) printf(" "); //注意格式,若m个数未被输出完毕,在输出的数字后紧跟一个空格
				else {
					printf("\n"); //若m个数字已经被输出完毕,则在输出的数字后面紧跟一个换行, 并跳出遍历循环
						break;
				}
			}
		}
	}
	return 0;
}
  • 注意点

①hash数组写main里面会栈溢出!!

②int型数据范围记一下:2147483647~-2147483648

③注意格式:最后一个数字输出后不带空格,这个是格式要求要扣分的!

④int型数组赋值的时候,若int A[10]={0};则全部为0;若int A[10]={1};则只有第一个是1,其他是0;

猜你喜欢

转载自blog.csdn.net/weixin_40614231/article/details/83714213