【题解】【AcWing】1638. 哈希 - 平均查找时间

99 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

1638. 哈希 - 平均查找时间

原题传送:AcWing 1638. 哈希 - 平均查找时间

这个问题的任务很简单:

首先将一个由若干个不同正整数构成的整数序列插入到一个哈希表中,然后尝试从表中查找另一个整数键值序列,并输出平均查找时间(查找时间指查找某个值是否在表中所进行的比较操作的次数)。

哈希函数定义为 H(key)=key%TSizeH(key)=key\%TSize ,其中 TSizeTSize 是哈希表的最大大小。

利用只具有正增量的二次探测法来解决冲突。

注意,哈希表的大小最好是素数,如果用户给出的最大大小不是素数,则必须将表大小重新定义为大于用户给出的大小的最小素数。

输入格式

第一行包含三个正整数 MSize,N,MMSize,N,M ,分别表示用户定义的表的大小,插入整数的数量,查找键值的数量。

第二行包含 NN 个不同的正整数,表示插入序列。

第三行包含 MM 个正整数,表示键值序列。

同行数字之间用空格隔开,两个序列中包含的整数均不超过 10510^5

输出格式

如果无法插入一些数字,则将其按顺序以如下格式输出,每个数字占一行:

X cannot be inserted.

其中X表示无法插入的数字。

最后一行输出 MM 次查找的平均查找时间,保留一位小数。

注意: 如果查找了 TSizeTSize 次,每次查找的位置上均有数,但都不等于要查找的数,则认为查找时间是 TSize+1TSize+1

数据范围

1MSize,N,M1041 \le MSize,N,M \le 10^4

输入样例:

4 5 4
10 6 4 15 11
11 4 15 2

输出样例:

15 cannot be inserted.
2.8

思路:

find函数传入引用变量cnt记录查找次数。

题解:

#include<bits/stdc++.h>

using namespace std;

const int N = 10010;

int msize, n, m;
int h[N];

int prime(int n)
{
	int i;
	
	for(i = 2; i <= sqrt(n); i++)
		if(n % i == 0)
			break;
			
	if(n <= 1)
		return 0;
	else if(i > sqrt(n))
		return 1;
	else
		return 0;
}

int find(int x, int &cnt)
{
	int t = x % msize;
	
	cnt = 1;
	for(int k = 0; k < msize; k++, cnt++)
	{
		int i = (t + k * k) % msize;
		if(!h[i] || h[i] == x)
			return i;
	}
	return -1;
}

int main()
{	
	scanf("%d%d%d", &msize, &n, &m);
	
	while(!prime(msize))
		msize++;
	
	for(int i = 0; i < n; i++)
	{
		int x, count;
		scanf("%d", &x);
		int t = find(x, count);
		
		if(t == -1)
			printf("%d cannot be inserted.\n", x);
		else
			h[t] = x;
	}
	
	int cnt = 0;
	for(int i = 0; i < m; i++)
	{
		int x, count;
		scanf("%d", &x);
		int t = find(x, count);
		cnt += count;
	}
	
	printf("%.1lf\n", 1.0 * cnt / m);

	return 0;
}