DFS - 单词接龙

来源:互联网 发布:php小游戏源代码 编辑:程序博客网 时间:2024/05/08 11:56

单词接龙

问题描述:

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


输入格式:

  输入的第一行为一个单独的整数n (n<=20)表示单词数,以下n 行每行有一个单词,输入的最后一行为一个单个字符,表示“龙”开头的字母。你可以假定以此字母开头的“龙”一定存在.

输出格式:

  只需输出以此字母开头的最长的“龙”的长度

样例输入:

5
at
touch
cheat
choose
tact
a

样例输出:

23

样例说明:

  连成的“龙”为atoucheatactactouchoose




#include<stdio.h>#include<stdlib.h>#include<string.h> char str[25][10];int map[25][25];int n, visited[25], max_sum;int length[25]; void init();void dfs(int i, int v);int change(char str1[], char str2[]); int main(){         int i, j;    int len1, len2, num, front, end, sum = 0;    char ch;     scanf("%d", &n);    for(i = 0; i < n; i++){        scanf("%s", str[i]);   //将输入的单词以字符串存储在str中        length[i] = strlen(str[i]);//将每个单词的长度 存储在length数组中,编号即为输入顺序    }         scanf(" %c", &ch);//得到开头的字符     for(i = 0; i < n; i++){        for(j = 0; j < n; j++){            map[i][j] = change(str[i], str[j]);//将各个单词之间的关系以邻接矩阵来表示,其中[i][j]表示从i到j的关系 ,值为重合的长度        }    }         for(i = 0; i < n; i++){        if(str[i][0] == 'a'){//找到满足作为【头】条件的单词            init();//初始化已访问记录数组            max_sum = 0;//初始化当前最大值为零            dfs(0, length[0]);//开始深度搜索可行方案,输入参数为第i个单词与第i个单词的长度            if(sum < max_sum){                sum = max_sum;   //此处为局部变量与全局变量的巧妙应用,此处 sum才是记录最大值,而 max_sum是当前最大值            }        }    }     printf("%d\n", sum);} int change(char str1[], char str2[]){//str1与str2的关系,返回值为重合部分的长度     int i, j;    int len1 = strlen(str1), len2 = strlen(str2);//存储两个字符串的长度    int front1, front2;    for(i = 0; i < len1; i++){        front1 = i; front2 = 0;        len2 = strlen(str2);        while(str1[front1] == str2[front2] && str1[front1] && str2[front2]){//重合则往后退一个            front1 ++; front2++;        }        if(front1 == len1 && i == 0){//str1包含于str2,不符合要求则重合部分为零            return 0;        }        else if(front1 == len1 && front2 == len2){//str2包含于str1,不符合要求则重合部分为零            return 0;        }        else if(front1 == len1 && i != 0 && front2 != len2){//有关系,返回重合长度            return (len1 - i);        }    }    return 0;//无重合部分,无关系}void dfs(int v, int sum){//输入的参数为当前的单词序号以及当前单词序号下可行的【龙】的长度         int i, var;         if(sum > max_sum){//如果当前龙长度大于记录中的龙长度,则更新记录        max_sum = sum;    }         for(i = 0; i < n; i++){        if(map[v][i] != 0 && visited[i] > 0){//如果存在关系且未被访问过            visited[i]--;//访问一次            dfs(i, sum + length[i] - map[v][i]);//深度遍历其子树            visited[i]++;//子树遍历完毕,恢复为访问前状态        }       }} void init(){    int i;    for(i = 0; i <= n; i++){        visited[i] = 2;//由于每个单词可出现两次,所以初始化为2    }}



【代码来源于网络,由于时间久远已经找不到原地址,在此致歉。仅作个人学习用,如有侵权我会删除】


0 0
原创粉丝点击