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
23
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;
} 

Posted by jstone3503 on Tue, 31 Dec 2019 20:52:14 -0800