求助各位大佬,这道题如何用hash表解
查看原帖
求助各位大佬,这道题如何用hash表解
492153
nanzjz1楼主2021/7/13 21:51

在一本通上面看到的这道题,但是书上把它划进了hash表的练习里面(数据范围稍小一点,为:1<=N<=100001<=N<=10000,1<=M<=5000001<=M<=500000) ,然而我尝试模仿书上的思路与深基中有关hash表部分的代码的时候只能AC5个点;并且空间占用很大,质数稍微取大一点就会MLE。

题解中的答案要么使用的是trie树,要么使用的是双哈希,还有暴力二分搜索的。

代码如下:

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
typedef unsigned long long ull;
const int p = 999983;//取模质数
vector<string>s[p + 2];//创建数组
bool used[p] = {0};//判断名字是否被点过
inline ull hash2(char a[])
{//求hash值
	ull res = 0; int len = strlen(a);
	for (int i = 0; i < len; i++)
	{
		res += 26 * res + (ull)a[i];
	}
	return res % p;
}
int main()
{
	int n, m; scanf("%d", &n);
	for (int i = 0; i < n; i++)
	{
		char a[52]; scanf("%s", a);
		string gjr = a;
		ull hashi = hash2(a);
		s[hashi].push_back(gjr);//读入数组元素
	}
	scanf("%d", &m);
	for (int i = 0; i < m; i++)
	{
		char a[52]; scanf("%s", a);
		string gjr = a;
		ull hashi = hash2(a); 
      bool symbol = 0;//对应hash值是否在数组中
		for (int u = 0; u < s[hashi].size(); u++)
		{//遍历hash值
			if (used[hashi])
			{//点过了就repet
				printf("REPEAT\n"); symbol = 1;
				break;
			}
			else
			{//没点过就ok 然后更改点名状态
				used[hashi] = 1;
				printf("OK\n"); symbol = 1;
				break;
			}
		}
		if (!symbol)//如果不在那就是点错了名
		{
			printf("WRONG\n");
		}
	}
	return 0;
}
2021/7/13 21:51
加载中...