题目描述
单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如 beast和astonish,如果接成一条龙则变为beastonish,另外相邻的两部分不能存在包含关系,例如at 和 atide 间不能相连。
输入输出格式
输入格式:
输入的第一行为一个单独的整数n (n<=20)表示单词数,以下n 行每行有一个单词,输入的最后一行为一个单个字符,表示“龙”开头的字母。你可以假定以此字母开头的“龙”一定存在.
输出格式:
只需输出以此字母开头的最长的“龙”的长度
输入输出样例
输入样例#1:
5
at
touch
cheat
choose
tact
a输出样例#1:
23
说明
连成的“龙”为atoucheatactactouchoose
源代码
# include<iostream>
# include<cstdio>
# include<string>
using namespace std;
int n;
string str[30];
int len_str,sum=0;
int times[30]={0};//存储单词出现次数
void dfs(int x)
{
int i,j;
int p,q;
int num;//存储不匹配的字符串个数
int work;
for(i=1;i<str[x].length();i++)
{
num=0;
for(j=1;j<=n;j++)
{
if(times[j]<2)//出现次数少于2次
{
if(str[x][i]==str[j][0])//依次比较当前字符串与字符串[j]的头是否相同
{
p=i,q=0,work=0;
while(p<=str[x].length()-1)//相同继续比较
{
if(str[x][p]!=str[j][q])//如果不同
{
num++;//不匹配的字符串个数+1
work++;
break;//终止
}
p++;
q++;
}
if(!work&&q!=str[j].length())//符合条件,进行操作
{
len_str+=str[j].length()-q;//累加长度
times[j]++;//累加次数
dfs(j);//继续向下搜索
len_str-=str[j].length()-q;//还原长度
times[j]--;//还原次数
}
}
else num++;//不同,不匹配的字符串个数+1
}
else num++;//大于两次,不匹配的字符串个数+1
}
if(num==n&&i==str[x].length()-1)//当不匹配个数与所给个数相同并且长度与所给的长度相同时
{
if(sum<len_str) sum=len_str;//如果最大长度小于字符串长度,令最大长度等于字符串长度
return;
}
}
}
int main()
{
int i;
cin>>n;//输入单词个数n
for(i=1;i<=n+1;i++) cin>>str[i];//输入n个单词
for(i=1;i<=n;i++)//令最后一个单词为龙头,寻找以龙头开头的字符串
if(str[i][0]==str[n+1][0])
{
times[i]++;//找到后,出现次数+1
len_str=str[i].length();//记录字符串长度
dfs(i);//开始搜索
}
cout<<sum<<endl;//输出最长长度
return 0;
}