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;
}