单词接龙 | |||||
| |||||
Description | |||||
单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如 beast和astonish,如果接成一条龙则变为beastonish,另外相邻的两部分不能存在包含关系,例如at 和 atide 间不能相连。 | |||||
Input | |||||
有多测测试数据。 对于每组测试数据,第一行为一个单独的整数n (n<=20)表示单词数,以下n 行每行有一个单词,输入的最后一行为一个单个字符,表示“龙”开头的字母。你可以假定以此字母开头的“龙”一定存在. | |||||
Output | |||||
只需输出以此字母开头的最长的“龙”的长度 | |||||
Sample Input | |||||
5 at touch cheat choose tact a | |||||
Sample Output | |||||
23 | |||||
Hint | |||||
样例中连成的“龙”atoucheatactactouchoose。 | |||||
Source | |||||
NOIp2000提高组 |
DFS~~~~~
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include <cstdio> 2 #include <cmath> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 using namespace std; 7 using namespace std ; 8 int map[25][25]; 9 int n,cnt; 10 char c; 11 char st[25][25]; 12 int visit[25]; 13 int dfs(int s) 14 { 15 int temp,maxlen=0,t=0; 16 for(int i=0;i<n;i++) 17 { 18 temp=0; 19 if(map[s][i]&&visit[i]) 20 { 21 t=1; 22 visit[i]--; 23 temp=dfs(i); 24 visit[i]++; 25 temp=temp+strlen(st[s])-map[s][i]; 26 } 27 if(temp>maxlen) maxlen=temp; 28 } 29 if(!t) return strlen(st[s]); 30 return maxlen; 31 } 32 int main() 33 { 34 while(scanf("%d",&n)!=EOF) 35 { 36 for(int i=0;i<n;i++) 37 scanf("%s",st[i]); 38 getchar(); 39 scanf("%c",&c); 40 memset(map,0,sizeof(map)); 41 int len1,len2; 42 for(int i=0;i<n;i++) 43 for(int j=0;j<n;j++) 44 { 45 len1=strlen(st[i]); 46 len2=strlen(st[j]); 47 for(int k=0;k<len1&&k<len2;k++) 48 { 49 if(strncmp(st[i]+len1-k-1,st[j],k+1)==0) 50 { 51 map[i][j]=k+1; 52 break; 53 } 54 } 55 } 56 for(int i=0;i<n;i++) visit[i]=2; 57 cnt=0; 58 int temp; 59 for(int i=0;i<n;i++) 60 { 61 if(st[i][0]==c) 62 { 63 visit[i]--; 64 temp=dfs(i); 65 if(temp>cnt) cnt=temp; 66 visit[i]++; 67 } 68 } 69 printf("%d\n",cnt); 70 } 71 }