OpenJudge 2.5-8783 单词接龙

来源:互联网 发布:c盘windows 编辑:程序博客网 时间:2024/05/16 12:28
Description

单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如beast和astonish,如果接成一条龙则变为beastonish,另外相邻的两部分不能存在包含关系,例如at和atide间不能相连。
Input
输入的第一行为一个单独的整数n(n<=20)表示单词数,以下n行每行有一个单词(只含有大写或小写字母,长度不超过20),输入的最后一行为一个单个字符,表示“龙”开头的字母。你可以假定以此字母开头的“龙”一定存在。
Output
只需输出以此字母开头的最长的“龙”的长度。
Sample Input
5attouchcheatchoosetacta
Sample Output
23

   在讲这道题之前,先说一点题外话:其实刚开始读到这道题的时候是抗拒的,所以一直没有去碰,后面是布置任务下来了才去做的,所以在面对一道题时不要有畏难情绪。其实这道题还是蛮简单的(虽然做了好久好久...)

   这种题一来果断string,用char的话就要定义二维,用string数组,一个元素就是一个单词。

   这道题据说有人是将龙全部接上去了的,我没有那么做,只计算了长度。思路就是回溯法,只不过最后那个判断外面要加一些东西:外层循环仍然枚举,枚举每一个单词,如果它的使用次数<2(需定义bool标记),就枚举被接龙单词的每一个字母,与接龙单词的首字母比较,找出接龙起点。记录下两个单词的接龙起点,再用while依次比对到被接龙单词末尾,如果while中被接龙单词的接龙起点到达了末尾(也就是说while循环到了最后,所有字母全都匹配,可以接龙),就开始接龙(回溯)。

    先奉上代码:

#include<cstdio>#include<string>#include<iostream>#include<algorithm>using namespace std;string a[21];int n,maxn,used[21],l=1;void dfs(int c)//a[c]已定单词,a[i]接龙单词{    int lc,li;    maxn=max(maxn,l);    for(int i=1;i<=n;i++)        if(used[i]<2)        {            for(int j=0;j<a[c].length();j++)//将已定单词的每一个字母逐一与接龙单词                if(a[c][j]==a[i][0])//的首字母比较,从相同的地方开始接                {lc=j;li=0;//记录接龙起点                    while(a[c][lc]==a[i][li]&&lc<a[c].length())//逐个比对,如果相同且长度没超过已定单词的长度就累加长度                    {                        lc++;                        li++;                    }                    if(lc==a[c].length())//如果比对到了,就接上长度(到达目标)                    {                        l+=a[i].length()-li;                        used[i]++;                        dfs(i);                        l-=a[i].length()-li;                        used[i]--;                    }                }        }}int main(){    scanf("%d",&n);    for(int i=1;i<=n;i++)        cin>>a[i];    cin>>a[n+1];    dfs(n+1);//把头字母也当成一个单词,从头字母开始搜    printf("%d",maxn);} 

有几点需要特别说明的:

1.它是要求最长,前面找接龙起点可以倒序找,只要找到一个就break,我这么写也会找到,因为我虽然顺序查找但是没有break,所以最终还是会查找到,但是耗时要长一些。

2.找接龙起点以及接龙长度(就是包括while那一段)可以用a.substr(i,j)这个函数来做,i表示查找起点(位置),j表示长度。

3.有一个我想了很久但是很懵的问题:我把lc,li定义在dfs()里面就没问题,但是定义在外面就会错。刚开始以为是回溯递归会影响到值,但是每次找到接龙起点时都重新附了值。然后我对比了两种方法lc,li以及a[i].lengrh()-li的值,都一样,但只要加上l(l+=a[i].lengrh()-li那里),值就会错,甚至有负数。



原创粉丝点击