Edit Step Ladders - UVa 10029 dp

本文讨论如何计算给定字典中最长的编辑步梯长度,通过哈希算法优化解决字符串转换问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值