Edit Step Ladders - UVa 10029 dp

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



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值