原题
试题 算法训练 单词接龙
资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如 beast和astonish,如果接成一条龙则变为beastonish,另外相邻的两部分不能存在包含关系,例如at 和 atide 间不能相连。
输入格式
输入的第一行为一个单独的整数n (n<=20)表示单词数,以下n 行每行有一个单词,输入的最后一行为一个单个字符,表示“龙”开头的字母。你可以假定以此字母开头的“龙”一定存在.
输出格式
只需输出以此字母开头的最长的“龙”的长度
样例输入
5
at
touch
cheat
choose
tact
a
样例输出
23
样例说明
连成的“龙”为atoucheatactactouchoose
思路简介
接龙本身思路不难,只需要用循环判断和查找即可。
主要是首字母这里的处理,以及每个单词只能使用两次的条件限制,需要细心。
首字母可以直接当成接龙单词的初始状态,这样不需要额外用循环来判断符合的单词,比较方便。
每个单词只能使用两次,那么用一个b数组标记就好,也不是问题。
参考代码如下:
#include <iostream>
using namespace std;
int n;
string s[22], ln;
char c;
int b[105];
int l;
void dfs()//还未判断每个单词只能使用两次
{
string z;
for (int j = ln.length() - 1; j >=0; j--)
{
z.append(ln.begin() + j, ln.end());
for (int k = 0; k < n; k++)
{
if (b[k]< 2 && s[k].compare(0, z.length(), z) == 0)
{
b[k]++;
int o = ln.length();
int p = s[k].length() - j;
ln.append(s[k].begin() + (ln.length() - j), s[k].end());
if (ln.length() > l)
{
l = ln.length();
}
dfs();
b[k]--;
ln.erase(o, ln.length() - 1);
}
}
z.clear();
}
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> s[i];
}
cin >> c;
ln = c;
dfs();
cout << l;
return 0;
}