DFS - 单词接龙
2016-05-02 22:49
405 查看
单词接龙
问题描述:
单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如 beast和astonish,如果接成一条龙则变为beastonish,另外相邻的两部分不能存在包含关系,例如at 和 atide 间不能相连。
输入格式:
输入的第一行为一个单独的整数n (n<=20)表示单词数,以下n 行每行有一个单词,输入的最后一行为一个单个字符,表示“龙”开头的字母。你可以假定以此字母开头的“龙”一定存在.
输出格式:
只需输出以此字母开头的最长的“龙”的长度
样例输入:
5
at
touch
cheat
choose
tact
a
样例输出:
23
样例说明:
连成的“龙”为atoucheatactactouchoose
【代码来源于网络,由于时间久远已经找不到原地址,在此致歉。仅作个人学习用,如有侵权我会删除】
问题描述:
单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如 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 } }
【代码来源于网络,由于时间久远已经找不到原地址,在此致歉。仅作个人学习用,如有侵权我会删除】
相关文章推荐
- 第6周 C语言及程序设计提高例程-24 数组名作为函数参数
- 为啥你手机还用不上安卓6.0?
- 关于Android MVC
- opencv画图的几个函数例程
- Oracle启动和关闭
- vim cuda语法高亮
- 写给工作不久就辞职的毕业生——关于转正、定职、定级
- 别蠢到用暴露自己软肋的方式,去表达你对别人的信任
- 关于接口,继承,内部类的一些测试
- 爬取外卖超人数据
- Kafka文件存储机制那些事
- Spring3.1集成Quartz,让你的任务执行随心所欲
- Java线程池——FutureTask
- Flink中的一些核心概念
- 类大小的计算
- struts2入门到精通教程
- 【转】Andorid获取状态栏高度
- Activity相关
- 代理模式
- HDU 1335 Basically Speaking (模拟进制转换)