题目连接:该题是luogu试炼场的2-7:T2
题目大意:
1 给出n,n个单词,首尾有重复就可以拼接在一起,要求如下:
2 每个单词只能最多用2次,单词之间不能完全包含。
3 求:最大的拼接长度。
解题思路:
1 吃果果的深搜,关键是要处理好:单词之间不能完全被包含
2 每个单词可以用2次,记得哦;
3细节请看代码,有详尽的注解
上代码:
//luogu1019:单词接龙
//单词拼接问题:每种情况都是一次;
#include<bits/stdc++.h>
using namespace std;
int n,b[50],l[50],su,ans=0;
char s[50][10005],st;
int d[50];
int pd(int x,int y)//判断:x和y能否拼接
{
int su,kk;
if(l[x]>=l[y])//前长
{
for(int tou=l[x];tou>=l[x]-l[y]+2;tou--)//从后往前尝试拼接
{
kk=0;
//s[x][i] vs s[y][j]
for(int i=tou,j=1;i<=l[x];i++,j++)
{
if(s[x][i]!=s[y][j])
{
break;
}
kk++;//计数器
}
if(kk==l[x]-tou+1) return l[y]-kk;//kk是匹配的数量
}
return -1;
}
else//后长
{
for(int tou=l[x];tou>=2;tou--)
{
kk=0;
for(int i=tou,j=1;i<=l[x];i++)
{
if(s[x][i]!=s[y][j])
{
break;
}
j++; kk++;
}
if(kk==l[x]-tou+1) return l[y]-kk;//kk是匹配的数量
}
return -1;
}
}
void dfs(int x,int de)//当前是第x个单词,从第de格开始
{
for(int i=1;i<=n;i++)
{
int k=pd(x,i);
if(b[i]>0 && k>0)//单词可用&&能拼接
{
b[i]--;su+=k;
d[de]=i;
if(ans<su) ans=su;
dfs(i,de+1);
b[i]++;su-=k;
}
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%s",s[i]+1);
b[i]=2;//每个单词可以拼接 2 次
l[i]=strlen(s[i]+1);
}
scanf("%s",&st);//龙头
for(int i=1;i<=n;i++)
{
if(s[i][1]==st)//每人都试一下做开头
{
b[i]=1; d[1]=i;
su=l[i]; //当前的长度
if(ans<su) ans=su;//更新答案
dfs(i,2);//当前是第i个单词,从第2格开始
b[i]=2;
}
}
printf("%d",ans);
return 0;
}