测评会员优惠活动进行中 · 开通 VIP,有效期内测评不限次 VIP 优惠中 · 测评不限次 立即查看

A26679. 单词接龙

填空题 困难

题目描述

单词接龙

题目描述

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

输入

输入的第一行为一个单独的整数n(n<=20)表示单词数,以下n行每行有一个单词(只含有大写或小写字母,长度不超过20),输入的最后一行为一个单个字符,表示“龙”开头的字母。你可以假定以此字母开头的“龙”一定存在。

输出

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

输入样例

5
at
touch
cheat
choose
tact
a

输出样例

23

参考答案

#include<bits/stdc++.h> using namespace std; #define N 25 int n, mxLen, vis[N];//mxLen:龙最大长度 vis[i]:单词s[i]用了几次 string s[N];//s[i]:单词列表第i个单词 void dfs(string ls, int totLen)//ls:当前龙中最后字符串 { mxLen = max(totLen, mxLen);//取可能的最大的长度 for(int i = 1; i <= n; ++i) if(vis[i] < 2)//只要用了不足2次 { for(int len = 1; len < ls.length() && len < s[i].length(); ++len)//由于重合部分不能包含单词,所以重合部分长度要小于两单词的长度 {//将ls末尾len个字符截取出来,看和s[i]前len个字符是否相同 if(ls.substr(ls.length()-len) == s[i].substr(0, len))//只要找到一个可以接上的情况,就不再找了,再找到的不会是最长的龙 { vis[i]++;//s[i]多用了1次 dfs(s[i], totLen+s[i].length()-len);//总长度增加s[i].length() - len vis[i]--; break;//只取len最小的接龙情况 } } } } int main() { char stch;//起始字符 cin >> n; for(int i = 1; i <= n; ++i) cin >> s[i]; cin >> stch; for(int i = 1; i <= n; ++i) if(s[i][0] == stch)//如果起始字符和s[i]首字符相同 {//以s[i]起始 vis[i]++; dfs(s[i], s[i].length()); vis[i]--;//恢复状态 } cout << mxLen; return 0; }
上一题 下一题