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;
}
上一题
下一题