发个题解存个码...(顺便刷一下题解指标...)
B - 单词接龙
单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如 beast和 astonish,如果接成一条龙则变为 beastonish ,另外相邻的两部分不能存在包含关系,例如 at 和 atide 间不能相连。
输入格式
输入的第一行为一个单独的整数 n (n \le 20)n(n≤20) 表示单词数,以下 nn 行每行有一个单词,输入的最后一行为一个单个字符,表示“龙”开头的字母。你可以假定以此字母开头的“龙”一定存在。
输出格式
只需输出以此字母开头的最长的“龙”的长度。
样例说明
连成的“龙”为 atoucheatactactouchoose
Sample Input
5 at touch cheat choose tact a
Sample Output
23
#include<cstdio>
#include<iostream>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;
string word[20];
string head;
int state[20] = { 0 }, length = 0, n;
int cutlong(string target1, string target2) {
int p = target1.length(), q = target2.length();//数组长度
int low = min(p, q);
for (int i = 1; i < low; i++) {
int t = 1;//一个标志变量
for (int j = 0; j < i; j++) {//暴力搜索重复段,i表示当前段的长度,j表示当前位,同时两者也可做计数
if (target1[p - i + j] != target2[j])
t = 0;//有不相等的,继续寻找
}
if (t) return i;/*这有个疑问(或者说是bug)不知道咋调(试了一下居然通过了,
我怀疑数据不全),就是比如两个单词dabab和ababs,我这个方法
判断的重合数是2,但其实应该是4...想再设一个标志变量记录最后
相等的位置好像没成功,如果各位神人有思路的话...求解!!!评
论或私信都行!!!*/
}
return 0;//全都不相等,段长度为0(想了半天没想到能把俩return融合的方法)
}
void dfs(string tail,int newlength) {
length = max(length, newlength);//记录当前的龙的长度
for (int i = 0; i < n; i++) {
if (state[i] >= 2) continue;//用了两次就不能再用了(如果有人不理解等于...出现大于二的数不就相当于用了超过两次了么)
int lon = cutlong(tail, word[i]);
if (lon > 0) {
state[i]++;//当前使用的单词用的次数+1
dfs(word[i], newlength + word[i].length() - lon);//新的龙尾和总长
state[i]--;//每次递归的时候都会多加一遍,这里减去
}
}
}
int main() {
cin >> n;
for (int i = 0; i < n; i++)
cin >> word[i];
cin >> head;
//为了把表示龙开头的字母当做单词作为龙头来起手,只能加长该字母(空格补长度,用
//符号数字也行,总之不要用字母啦),因为题目要求不能有包含关系
dfs(' ' + head, 1);//开头字母算一个单词(此时),所以衔接长度从1开始。(这个无所谓了...)
cout << length;
}