洛谷Oj-单词接龙-深度优先搜索

来源:互联网 发布:华为盒子看电影软件 编辑:程序博客网 时间:2024/06/06 10:02

问题描述
单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如 beast和astonish,如果接成一条龙则变为beastonish,另外相邻的两部分不能存在包含关系,例如at 和 atide 间不能相连。
AC代码

int book[1001],len=0,n;//数组book用来查重,len记录龙的最长长度,n记录单词的个数char word[1001][501];//数组word用来保存单词int mat(char a[],char b[])//重点+难点,匹配函数mat(ch){    int i,j,min,num,nn;//num记录匹配的字母的个数,    if(strlen(a)<strlen(b))//min记录字符串a的长度和字符串b的长度中的较小值        min=strlen(a);    else        min=strlen(b);    for(i=1;i<=min;i++)//循环范围为1到min,防止数组访问越界    {        num=0;//重置变量        nn=0;        for(j=strlen(a)-i;j<=strlen(a)-1;j++)        {            if(b[nn]==a[j])//数组a的尾部与数组b的头部            {                num++;                nn++;            }            else//如果有字母不相同,就将num赋为0,即此次匹配失败            {                num=0;                break;            }        }        if(num!=0&&num!=strlen(a)&&num!=strlen(b))//如果num的值非0且不等于min记录字符串a的长度或字符串b的长度            return num;        else if(num==strlen(a)||num==strlen(b))//如果num的值等于字符串a的长度或字符串b的长度            return 0;    }    return 0;//无论如何都不匹配,无解,返回0}void dfs(char b[]){    int i,j,num,nn,mark;//num记录匹配的字母的个数    char a[501];//数组a用来接收数组b,不能直接对数组b进行操作,否则会改变word数组    strcpy(a,b);//复制    if(strlen(a)>len)        len=strlen(a);//更新最长长度    for(i=1;i<=n;i++)//遍历每个单词    {        mark=strlen(a);//记录当前字符串状态的长度        nn=strlen(a);//nn在接下来的操作中,其值改变        if(book[i]<=1&&(num=mat(a,word[i]))!=0)//如果该单词的使用次数低于2次且与当前字符串状态匹配        {            for(j=num;j<=strlen(word[i])-1;j++)//将该单词接在后面            {                a[nn]=word[i][j];                nn++;            }            a[nn]='\0';//小细节,防止出错            book[i]++;//使用次数+1            dfs(a);递归            book[i]--;//使用次数-1            for(j=mark;j<=strlen(word[i])-num+mark-1;j++)//此时mark派上用场,将接上的单词消去                a[j]='\0';        }    }    return;}int main(){    int i;    char c;    scanf("%d",&n);//输入    for(i=1;i<=n;i++)        scanf("%s",word[i]);    //scanf("\n%c",&c);//如果要使用scanf来输入,就要加一个\n    cin>>c;    for(i=1;i<=n;i++)//遍历每个单词        if(word[i][0]==c)//如果其开头字母为c        {            book[i]++;//使用次数+1            dfs(word[i]);//以其为起点开始搜索            book[i]--;//使用次数-1        }    printf("%d\n",len);//打印    return 0;}

解决方法
解决这道问题最需要注意的就是匹配函数,因为要求得最长的龙,所以求出的匹配数要求最小,还要考虑一个也不匹配的情况和完全匹配的情况。
dfs中没设边界条件,因为当执行完循环后函数自然会返回。

原创粉丝点击