现在的位置: 首页 > 综合 > 正文

UVA 188 Perfect Hash

2019年04月08日 ⁄ 综合 ⁄ 共 823字 ⁄ 字号 评论关闭

大意:找最小的C,使得所有的单词在hash表中的位置不冲突。

思路:照着模拟,注意一个单词时的w[i]的算法,然后去找(C/w[i]) % n == (C/w[j])有冲突的点,然后按照题目给的公式递推即可,如果C!=next,则说明next == C,所有的冲突已经避免了。

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;

const int MAXN = 256;
char str[MAXN];

typedef unsigned long long ULL;

ULL w[MAXN];

char save[MAXN];

void init()
{
	memset(w, 0, sizeof(w));
}

void solve()
{
	init();
	int len = strlen(str);
	int n = 0;
	for(int i = 0, k = 0;; i++)
	{
		if(str[i] && isalpha(str[i]))
		{
			save[k++] = str[i];
		}
		else if(k > 0)
		{
			for(int j = 0; j < k; j++)
			{
				w[n] = w[n]*32 + (save[j] - 'a' + 1);
			}
			n++;
			k = 0;
		}
		if(str[i] == 0) break;
	}
	ULL temp, next = 1;
	ULL C;
	do
	{
		C = next;
		for(int i = 0; i < n; i++)
		{
			for(int j = i+1; j < n; j++)
			{
				if((C/w[i])%n == (C/w[j])%n)
				{
					temp = min(((C/w[i])+1)*w[i], ((C/w[j])+1)*w[j]);
					next = max(next, temp);
				}
			}
		}
	}while(next > C);
	printf("%s\n", str);
	printf("%llu\n\n", C);
}

int main()
{
	while(gets(str))
	{
		solve();
	}
	return 0;
}

抱歉!评论已关闭.