题目描述
单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如 beast和astonish,如果接成一条龙则变为beastonish,另外相邻的两部分不能存在包含关系,例如at 和 atide 间不能相连。
输入格式
输入的第一行为一个单独的整数n (n<=20)表示单词数,以下n 行每行有一个单词,输入的最后一行为一个单个字符,表示“龙”开头的字母。你可以假定以此字母开头的“龙”一定存在.
输出
只需输出以此字母开头的最长的“龙”的长度
样例输入
5
at
touch
cheat
choose
tact
a
样例输出
23
思路:找到以"龙"开头的单词,从其后往前,找到以该单词中字母开头的另一个单词,接着搜索。

1 #include<iostream> 2 #include<cstring> 3 #include<string> 4 using namespace std; 5 string word[22]; 6 int vis[30]; 7 int N; 8 int ans; 9 bool flag = false; 10 void dfs(string str, int o) 11 { 12 int i, j, k, s, len1, len2, pos; 13 if(vis[o] > 2)return ; 14 if((len1 = str.size()) > ans)ans = str.size(); 15 for(i = 0; i < N; i++){ 16 if(vis[i] < 2){//选出可用的单词 17 flag = false; 18 for(pos = len1-1; pos >= 0; pos--){ 19 if(str[pos] == word[i][0]){//pos位置与单词第一个字母相同 20 len2 = word[i].size();// 21 for(k = pos,s = 0; k < len1 && len1-pos<len2; k++,s++){ 22 if(str[k] != word[i][s])break; 23 } 24 if(len1-pos == s){flag = true;break;} 25 } 26 } 27 if(flag == true){ 28 string t = str; 29 t.append(word[i], s, len2-s);//向t添加多出的部分s位置起,len2-s个字符 30 if(t.size() > ans)ans = t.size(); 31 vis[i]++; 32 dfs(t, i); 33 vis[i]--; 34 } 35 } 36 37 } 38 } 39 int main() 40 { 41 int i, j; 42 char top; 43 cin>> N; 44 for(i = 0; i < N; i++){ 45 cin>> word[i]; 46 } 47 cin>> top; 48 for(i = 0; i < N; i++){ 49 if( top == word[i][0] ){ 50 vis[i]++; //每个单词最多出现两次 51 dfs(word[i], i); //第i个单词能接上龙头 52 memset(vis, 0, sizeof(vis)); 53 } 54 } 55 cout<<ans<<endl; 56 return 0; 57 }