题意:
1.给出n个单词,然后根据题上的规则保证给出的每个单词在“龙"中最多出现2次;
2.每个相邻连接的单词不能存在包含关系(但是我说实话eye这个单词你说最大长度是多少?答案居然给的5。。。。eye不是eye的子集吗?怎么这也不算包含,搞得我judge算长度算错了);
3.按照最后给出的单个字符的单词作为龙头.
问连接出来的最长的字符串长度是多少?
很明显这道题直接dfs一下就OK了,有个难点在于如何求连接的长度;
直接枚举即可;
AC代码:
#include<bits/stdc++.h>
using namespace std;
int book[50];
string s[50];
int ans;
int n;
int judge(string s1,string s2){
//枚举,定s1,从后面开始枚举
int res=0;
int len1=s1.length(),len2=s2.length();
for(int i=len1-1;i>=0;i--){
if(s1[i]==s2[0]){
int j,k,t=0;
for(j=i,k=0;j<len1&&k<len2;j++,k++){
if(s1[j]==s2[k])t++;
else break;
}
if(j==len1){
res=max(res,t);break;//这里需要break;因为以防eye这种单词出现因为eyeye 可以拼接
}
}
}
return res;
}
void dfs(int fr,int len){
//这里可以把dfs当做一个节点,存的是先前的单词和长度
ans=max(ans,len);//每次记录最大值
for(int i=0;i<2*n;i++){
//枚举其他的没有被标记的单词
if(!book[i]){
//如果没有被标记
int t=judge(s[fr],s[i]);//求当前的单词和先前的单词重合的长度
if(t==s[fr].length()||t==s[i].length()||t==0)continue;//如果存在包含关系,或者不包含,那么就不用标记
else {
book[i]=1;
dfs(i,len+s[i].length()-t);//向下搜索,这里的len是前面已经拼好的单词的字符串长度,这里传下去的是拼好s[i]这个字符串之后的长度
book[i]=0;
}
}
}
}
int main(){
scanf("%d",&n);
for(int i=0;i<n;i++){
cin>>s[i];
}
for(int i=n;i<2*n;i++){
//因为说最多两次,所以我复制一次
s[i]=s[i-n];
}
char c;
cin>>c;
for(int i=0;i<2*n;i++){
//枚举每个单词
if(s[i][0]==c&&!book[i]){
//这个单词没有被标记过
book[i]=1;
dfs(i,s[i].length());//表示当前选已经的这个单词的下标i和单词的长度
book[i]=0;
}
}
printf("%d\n",ans);
return 0;
}