问题描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如 beast和astonish,如果接成一条龙则变为beastonish,另外相邻的两部分不能存在包含关系,例如at 和 atide 间不能相连。 输入格式 输入的第一行为一个单独的整数n (n<=20)表示单词数,以下n 行每行有一个单词,输入的最后一行为一个单个字符,表示“龙”开头的字母。你可以假定以此字母开头的“龙”一定存在. 输出格式 只需输出以此字母开头的最长的“龙”的长度 样例输入 5 at touch cheat choose tact a 样例输出 23 样例说明 连成的“龙”为atoucheatactactouchoose
记:
思路在代码中体现
AC代码:
1 #include <stdio.h> 2 #include <string.h> 3 #define LEN 20 4 #define MAX 10010 5 6 int n; /*单词的个数*/ 7 int max = 0; /*最长的"龙"长度*/ 8 char ans[MAX+1]; /*最长的"龙"内容*/ 9 char arr[LEN+1][MAX+1]; /*存储单词*/ 10 int vis[LEN+1] = {0}; /*每个单词的访问记录*/ 11 12 void init() 13 { 14 int i; 15 scanf("%d",&n); 16 for (i = 0 ; i <= n ; i ++) 17 { 18 scanf("%s",&arr[i]); 19 } 20 return ; 21 } 22 23 int check(int x,char tmp[MAX+1]) 24 { 25 int i,j,k; 26 int len = 0,len2 = 0; 27 28 len = strlen(tmp)-1; /*原"龙"的长度*/ 29 len2 = strlen(arr[x])-1;/*将添加单词的长度*/ 30 for (i = len ; i >= 0 && len2; i --,len2 --) 31 { 32 if (tmp[i] == arr[x][0])/*找到将添加单词的头*/ 33 { 34 k = 1; 35 /*检查该单词是否能接"龙"*/ 36 for (j = i+1 ; j <= len ; j ++,k ++) 37 { 38 if (tmp[j] != arr[x][k]) 39 { 40 break;/*不能接龙*/ 41 } 42 } 43 44 /*该单词能接"龙"*/ 45 if (j>len) 46 { 47 return i;/*返回接龙的位置*/ 48 } 49 } 50 } 51 52 return 0; 53 } 54 55 void dfs(char tmp[MAX+1]) 56 { 57 int i,j; 58 int len = 0; 59 char add[MAX+1]; 60 61 for (i = 0 ; i < n ; i ++) 62 { 63 if (vis[i] < 2)/*检查次数*/ 64 { 65 len = check(i,tmp);/*检查能否接龙,0->不能,1->能*/ 66 if (len) 67 { 68 /*将单词接到"龙"上*/ 69 for (j = 0 ; j < len ; j ++) 70 { 71 add[j] = tmp[j]; 72 } 73 strcat(add,arr[i]); 74 vis[i]++; 75 dfs(add); 76 vis[i]--; 77 memset(add,0,sizeof(add)); 78 } 79 } 80 } 81 82 len = strlen(tmp); 83 if (len > max) 84 { 85 max = len; /*更新最长的"龙"长度*/ 86 //strcpy(ans,tmp);/*更新最长的"龙"内容*/ 87 } 88 return ; 89 } 90 91 int main(void) 92 { 93 int i; 94 init(); 95 for (i = 0 ; i < n ; i ++) 96 { 97 /*以最后一个单词为头的单词*/ 98 if (arr[i][0] == arr[n][0]) 99 { 100 vis[i]++; 101 dfs(arr[i]); 102 vis[i]--; 103 } 104 } 105 printf("%d",max); 106 return 0; 107 }