题目链接:
类型: 哈希
原题:
Perfect Software, Inc. has obtained a government contract to examine text flowing through a high-speed network for the occurrence of certain words. Your boss, Wally Perfect, has designed a parallel processing system which checks each word against a group of small perfect hash tables.
A perfect hash function maps its input directly to a fully occupied table. Your job is to construct the perfect hash functions from the lists of words in each table. The hash function is of the form, whereCis a positive integer you are to discover,wis an integer representation of an input word, andnis the length of the table.Cmust be as small as possible. Note thatis the floor function and thatfor some real numberRis the largest integer that is.
Here are Wally's notes on the subject:
Letconsist of positive integers. The problem is to find the smallest positive integerCsuch that
for all.
Cmust be a multiple of at least one element ofW.
If some
for all,
then the next largestCthat could resolve the conflict is at least
Since all such conflicts must be resolved, it is advantageous to choose the largest candidate from among the conflicts as the nextCto test.
You are to convert each word to a number by processing each letter from left to right. Consider `a' to be 1, `b' to be 2,, `z' to be 26. Use 5 bits for each letter (shift left by 5 or multiply by 32). Thus `a' = 1, `bz' =.
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 theCfor the hash function determined by the list. Print a blank line after eachC.
Cwill always fit in a 32-bit integer.
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
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是一个正数, 也就是你要找的那个数(结果要输出这个数)。w是由一个单词转换得到的数字,例如`a' = 1, `bz' =, 可以把它看成是32进制的转换。 n其实就是代表的是一行中的单词的个数。
然后怎样求出C呢?
首先对于,.是由一行中的各个单词转换而来的,然后题目说Cmust be a multiple of at least one element ofW. 也就是C必须是W中某一个的倍数, 然后再上面点还说Cmust be as small as possible. C必须尽可能地小。 所以,在开始时, 让C等于w1(w1是最小的,因为W集合已经排好序了:)。
对于C,要让它符合条件for all. 所以要用一个两层for循环来判断。
如果不符合的话,就让C等于:
一直到找到符合的条件C为止,答案就出来了。
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int n, W[15], C, ans; inline int min(int a, int b){ return a<b?a:b; } // 递归找出符合条件的C void solve( ){ for(int i=0; i<n; ++i){ for(int j=i+1; j<n; ++j)if((C/W[i])%n==(C/W[j])%n){ C = min((C/W[i]+1)*W[i], (C/W[j]+1)*W[j]); solve(); return ; } } } int main(){ char str[200]; int i; while(gets(str)){ n=0; memset(W, 0, sizeof(W)); for(i=0; i<=strlen(str); ++i){ if(str[i]==' ' || str[i]=='\0'){ ++n; while(str[i+1]==' ')++i; // 跳过连续的空格 } else{ W[n] = (W[n]<<5)+str[i]-'a'+1; } } sort(W, W+n); // 排序,让w1<w2<w3...<wn C = W[0]; solve(); puts(str); printf("%d\n", C); puts(""); } return 0; }
—— 生命的意义,在于赋予它意义。