NOIP2000 improvement group T3 word connection
Keywords:
C++
Problem surface
Word Solitaire is a game similar to the idiom Solitaire we often play. Now we know a group of words, and given an initial letter, we need to give the longest "dragon" that starts with this letter (each word appears twice in the "dragon" at most). When two words are connected, their overlapping parts are combined into one part, such as beastbeast and astonishastonish ish, If it is connected into a dragon, it becomes beastonish beastonish. In addition, the two adjacent parts cannot have inclusion relations, for example, atat and atideide cannot be connected.
I / O format
Input format:
The first line of input is a single integer n n (n \le 20n ≤ 20) indicating the number of words. Each line of the following nn line has a word. The last line of input is a single character, indicating the letter beginning with "dragon". You can assume that there must be a dragon beginning with this letter
Output format:
Just output the length of the longest "dragon" starting with this letter
Example:

5
at
touch
cheat
choose
tact
a
input


output
thinking
First, we record the shortest overlapped part of x to y with calc array. Then dfs can be used. t array is assigned first, and then a flag record can be opened. If it can be connected, the max value can not be updated
Code
#include<bits/stdc++.h>
using namespace std;
string s[25];
char start;
int n,t[25],len[25],calc[25][25],maxx=-1,ans=0;
int pub(int x, int y){
bool f=1;
int top=0;
for(int i=len[x];i>=0;i--)
{
f=1;
for(int j=i;j<=len[x];j++) if(s[x][j]!=s[y][top++]){f=0;break;}
if(f==1) return len[x]-i+1;
top=0;
}
return 0;
}
void dfs(int x)
{
bool flag=false;
for (int i=1;i<=n;i++)
{
if (t[i]==0) continue;
if (calc[x][i]==0) continue;
if(calc[x][i]==len[x]+1||calc[x][i]==len[i]+1) continue;
t[i]--;
ans+=len[i]+1-calc[x][i];
flag=true;
dfs(i);
t[i]++;
ans-=len[i]+1-calc[x][i];
}
if(flag==false) maxx=max(maxx,ans);
}
int main()
{
cin>>n;
for (int i=1;i<=n;i++) t[i]=2;
for (int i=1;i<=n;i++) cin>>s[i],len[i]=s[i].size()-1;
cin>>start;
// for (int i=1;i<=n;i++) cout<<s[i]<<" "<<len[i]<<endl;
for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) calc[i][j]=pub(i,j);
// for (int i=1;i<=n;i++)
// {
// for (int j=1;j<=n;j++)
// cout<<calc[i][j]<<" ";
// cout<<endl;
// }
for (int i=1;i<=n;i++) if (s[i][0]==start) t[i]--,ans=len[i]+1,dfs(i),t[i]=2;
cout<<maxx<<endl;
}