Problem C: Edit Step Ladders
An edit step is a transformation from one word x to another word y such that x and y are words in the dictionary, and x can be transformed to y by adding, deleting, or changing one letter. So the transformation from dig to dog or from dog to do are both edit steps. An edit step ladder is a lexicographically ordered sequence of words w1, w2, ... wn such that the transformation from wi to wi+1 is an edit step for all i from 1 to n-1 .
For a given dictionary, you are to compute the length of the longest edit step ladder.
Input
The input to your program consists of the dictionary - a set of lower case words in lexicographic order - one per line. No word exceeds 16 letters and there are no more than 25000 words in the dictionary.Output
The output consists of a single integer, the number of words in the longest edit step ladder.Sample Input
cat dig dog fig fin fine fog log wine
Sample Output
5
题意:每次操作可以使前一个字符串改变一个字符,增加一个字符或减少一个字符来得到下一个字符串,从输入数据中选出一定的字符串,问符合的最大个数是多少。
思路:哈希做法,比如dog这个字符串,可以变成他的为#og,d#g,do#,#dog,d#og,do#g,dog#,这几种情况,哈希之后得到这些情况中连续数目最大的,那么到dog这里就是这个最大数目+1,同时更新以上这些的最大值。网上其他人的代码都好长,就懒得看了额,于是乎还是自己写的好。
AC代码如下:
#include<cstdio>
#include<cstring>
#include<map>
using namespace std;
typedef unsigned long long ull;
map<ull,int> match;
ull f[100],n,m,len[25010];
char s[25010][20];
void Hash(int pos)
{ int i,j,k,num=0;
for(i=1;i<=len[pos];i++)
{ f[++num]=0;
for(j=1;j<=len[pos];j++)
{ f[num]*=1000007;
if(j==i)
f[num]+=28;
else
f[num]+=s[pos][j]-'a'+1;
}
}
if(len[pos]<16)
for(i=0;i<=len[pos];i++)
{ f[++num]=0;
if(i==0)
f[num]=28;
for(j=1;j<=len[pos];j++)
{ f[num]*=1000007;
f[num]+=s[pos][j]-'a'+1;
if(i==j)
{ f[num]*=1000007;
f[num]+=28;
}
}
}
f[0]=num;
}
int main()
{ int i,j,k,ans=0,ret;
while(~scanf("%s",s[++n]+1))
{ len[n]=strlen(s[n]+1);}
for(i=1;i<=n;i++)
{ Hash(i);
ret=0;
for(j=1;j<=f[0];j++)
ret=max(ret,match[f[j]]);
ret++;
for(j=1;j<=f[0];j++)
match[f[j]]=max(match[f[j]],ret);
ans=max(ans,ret);
}
printf("%d\n",ans);
}