P1019 单词接龙
题目描述
单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如 beast和astonish,如果接成一条龙则变为beastonish,另外相邻的两部分不能存在包含关系,例如at 和 atide 间不能相连。
输入输出格式
输入格式:
输入的第一行为一个单独的整数n (n<=20)表示单词数,以下n 行每行有一个单词,输入的最后一行为一个单个字符,表示“龙”开头的字母。你可以假定以此字母开头的“龙”一定存在.
输出格式:
只需输出以此字母开头的最长的“龙”的长度
输入输出样例
输入样例#1:
5
at
touch
cheat
choose
tact
a
输出样例#1:
23 (连成的“龙”为atoucheatactactouchoose)
说明
NOIp2000提高组第三题
这是一道dfs+字符串
接龙的规则是前后字符串有相同的部分(一开始以为是单个字符)。
而且每个串只能用两次。
因为只有二十个串,所以可以直接用搜索
再说字符串的连接的判断。
先取后一个字符串的第一个字符,在前者由后往前找一个相同的字符。然后两个指针分别判断由此到最后一个字符是否全部相同。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdio>
using namespace std;
int vis[21];
int n;
char dragon[21][256];
int len[21];
int maxs = 0;
inline int read(){
char c;
int res,flag = 0;
while((c = getchar())>'9'||c<'0')
if(c=='-')flag = 1;
res = c - '0';
while((c = getchar())>='0'&&c<='9')
res =(res<<3)+(res<<1) + c - '0';
return flag?-res:res;
}
inline int check(int a,int b){
int i,k,j;
for(i=len[a]-1;i>=1;i--){
if(dragon[a][i]==dragon[b][0]){
int x=0;
for(k=i,j=0;k<len[a]&&j<len[b];k++,j++){
if(dragon[a][k]==dragon[b][j])x++;
else break;
}
if(k==len[a])return x;
}
}
return 0;
}
void dfs(int i,int lenx){
bool flag =true;
for (int j = 1;j<=n;j++){
if(vis[j] < 2){
int t = check(i,j);
if(t!=0){
flag = false;
vis[j]++;
dfs(j,lenx+len[j]-t);
vis[j]--;
}
}
}
if(flag == true){
maxs = max(maxs,lenx);
}
}
int main(){
n = read();
for (int i =1;i<=n;i++){
cin>>dragon[i];
len[i] = strlen(dragon[i]);
}
char c;
cin>>c;
memset(vis,0,sizeof(vis));
for (int i = 1;i<=n;i++){
if(dragon[i][0] == c){
vis[i]+=1;
dfs(i,len[i]);
memset(vis,0,sizeof(vis));
}
}
cout<<maxs;
}