题目描述 Description
单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如beast和astonish,如果接成一条龙则变为beastonish,另外相邻的两部分不能存在包含关系,例如at和atide间不能相连。
输入描述 Input Description
输入的第一行为一个单独的整数n(n<=20)表示单词数,以下n行每行有一个单词,输入的最后一行为一个单个字符,表示“龙”开头的字母。你可以假定以此字母开头的“龙”一定存在.
输出描述 Output Description
只需输出以此字母开头的最长的“龙”的长度
样例输入 Sample Input
5
at
touch
cheat
choose
tact
a
样例输出 Sample Output
23
数据范围及提示 Data Size & Hint
(连成的“龙”为atoucheatactactouchoose)
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int n,con[21][21],visited[21],ans; char dict [21][110],st; int lenn (int a,int b)//处理a单词后面连b单词,其中的重叠部分 { int len1=strlen(dict[a]),len2=strlen(dict[b]); for (int i=len1-1;i>0;i--) { if (len1-i==len2)break; bool flag=1;int kount=0; for (int j=i;j<len1;j++) { //printf ("%c %c\n",dict[a][j],dict[b][j-i]); if (dict[a][j]!=dict[b][j-i])flag=0; } if (flag){/*printf ("%s %s %d\n",dict[a],dict[b],len1-i);*/return con[a][b]=len1-i;} } //printf ("%s %s 0\n",dict[a],dict[b]); return 0; } void dfs (int a,int len)// dfs (a,len)表示当前状态中最后一个单词是a,龙长度是len { //printf ("%s %d\n",dict[a],len); bool flag=1; for (int i=1;i<=n;i++) if (con[a][i] && visited[i]<2) { visited[i]++;dfs(i,len+strlen(dict[i])-con[a][i]);visited[i]--;flag=0; } if (flag)ans=max(ans,len); //printf ("return\n");return; } int main () { scanf ("%d",&n); for (int i=1;i<=n;i++) { scanf ("%s\n",dict[i]);/*printf ("%d %s\n",i,dict[i]);*/} scanf ("%c",&st);//printf ("%c\n",st); for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) lenn(i,j); for (int i=1;i<=n;i++)//可以开始深搜的话就开始。。 if (dict[i][0]==st) { memset (visited,0,sizeof(visited));visited[i]++;dfs (i,strlen(dict[i]));/*printf ("----------\n");*/} //printf ("%d\n",lenn(1,1)); //printf ("con[5][4]=%d\n",con[5][4]); printf ("%d\n",ans); return 0; } //Copyright (C) 2014 wikioi user12923 All rights reserved