Uva--188 Perfect Hash

Input

Input to your program will be a series of word lists, one per line, terminated by the end-of-file. Each line consists of between two and thirteen words of at most five lower case letters each, separated from each other by at least one blank. There will always be at least one one-letter word.

For each list, you are to print the input line. On the next line, print the C for the hash function determined by the list. Print a blank line after each C.

C will always fit in a 32-bit integer.

Sample Input

this is a test of some words to try out

a bee see dee

the of and to a in that is i it with for as

Sample Output

this is a test of some words to try out

17247663

 

a bee see dee

4427

 

the of and to a in that is i it with for as

667241

题目大意

让我们找到一个C,使所有单词的哈希值不同。

C必须为w集合中的数(W:就是每个单词对于对应的哈希值);

根据公式:最小的C的算法,满足(图一)的式子的情况下,然后用(图二)的式子去算C的最小值。

要是得到两个相同的哈希值,根据

计算出新的C。

最后输出最小的C。

题目里n就是单词的个数。

提示:

注:因为要求最小,所以一开始只要让C=W[0]即可。此时W已经排序。

例:(bee=b*32*32+e*32+e=2*32+32+5*32+5=2208(bee对应的哈希值)(ps:32进制))

 

图一:

图二:

废话不多说,代码如下:

 

#include<cstdio>
#include<string>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
char s[10000];//每句话 
int w[1000];//单词对于的哈希值 
int main()
{
	//freopen("1.txt","r",stdin);
	//freopen("2.txt","w",stdout);
	while(gets(s))
	{
		
		int l=strlen(s);
		int n=0;
		int num=0;
		int e=1;
		for(int i=l-1;i>=0;i--)	//倒着扫,遇到空格开始计算哈希值 
		{
			if(s[i]>='a'&&s[i]<='z') 
			{
				int t;
				t=s[i]-'a'+1;
				num+=e*t;
				e*=32;
			}
			if( (s[i]==' '&&s[i-1]!=' ')||i==0 )//注意顺序 ,ps:就是少了个i==0和没注意顺序,这让坑我了好多次 , 
			{
				w[n++]=num;
				num=0;
				e=1;
				continue;
			}		
		}
		sort(w,w+n);//切记要排序,方便后续查找C值 
		int C=w[0];
		bool flag=true;
		while(flag)
		{
			flag=false;
			for(int i=0;i<n;i++)
			{
				for(int j=i+1;j<n;j++)
				{
					if(C/w[i]%n==C/w[j]%n)//图一公式 
					{
						flag=true;
						C=min( ( C/w[i]+1)*w[i], (C/w[j]+1)*w[j] );//图二公式 
					}
				}	
			}		
		}
		printf("%s\n%d\n\n",s,C);  //注意格式 
	}
	return 0;
}

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值