题目描述
单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如 beast和astonish,如果接成一条龙则变为beastonish,另外相邻的两部分不能存在包含关系,例如at 和 atide 间不能相连。
输入输出格式
输入格式:
输入的第一行为一个单独的整数n (n<=20)表示单词数,以下n 行每行有一个单词,输入的最后一行为一个单个字符,表示“龙”开头的字母。你可以假定以此字母开头的“龙”一定存在.
输出格式:
只需输出以此字母开头的最长的“龙”的长度
输入样例:
5
at
touch
cheat
choose
tact
a
输出样例#1
23 (连成的“龙”为atoucheatactactouchoose)
#include<iostream>
#include<cstdio>
#include<string>
#include<cmath>
using namespace std;
int n;
string words[25];
int overlap[25][25];
int times[25];
int ans = -1;
int an = 0;
char beg;
int MOL(int x, int y){ //MLL for minimum overlap length
bool flag = true;
int back_y = 0;
for(int fro_x = words[x].size() - 1; fro_x >= 0; fro_x--){
for(int back_x = fro_x; back_x < words[x].size(); back_x++){
if(words[x][back_x] != words[y][back_y]){
flag = false;
break;
}
back_y++;
}
if(flag){
return words[x].size() - fro_x;
}else{
back_y = 0;
flag = true;
}
}
return 0;
}
void dfs(int p){
bool flag = false;
for(int j = 1; j <= n; j++){
if(times[j] >= 2) continue;
if(overlap[p][j] == 0) continue;
if(overlap[p][j] == words[p].size() || overlap[p][j] == words[j].size()) continue;
an += (words[j].size() - overlap[p][j]);
times[j]++;
flag = true;
dfs(j);
an -= (words[j].size() - overlap[p][j]);
times[j]--;
}
if(flag == false){
ans = max(ans, an);
}
}
int main(){
scanf("%d", &n);
for(int i = 1; i <= n; i++)
cin>>words[i];
cin>>beg;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
overlap[i][j] = MOL(i, j);
for(int i = 1; i <= n; i++)
if(words[i][0] == beg){
times[i]++;
an = words[i].size();
dfs(i);
times[i]--;
}
printf("%d\n", ans);
return 0;
}