【ACWing】1117. Word Solitaire

Subject address:

https://www.acwing.com/problem/content/1119/

Word Solitaire is a game similar to the idiom Solitaire we often play. Now we know a set of words, and given a letter at the beginning, ask for the longest "dragon" beginning with this letter, and each word can be used at most twice. When two words are connected, their overlapping parts are combined into one part, such as beastsum astonish, which becomes a dragon if they are connected together beastonish.

We can choose the length of the overlapping part arbitrarily, but its length must be greater than or equal to 1, and strictly less than the length of the two strings, for example, atand atidecannot be connected.

Input format:
the first line of input is a single integer nnn represents the number of words, the followingnnThere is one word in each line of n lines (only uppercase or lowercase letters, length not exceeding20 202 0 ), the last act input a single character, represents the letter "Dragon" at the beginning. You can assume that the "dragon" beginning with this letter must exist.

Output format:
just output the length of the longest "dragon" beginning with this letter.

Data range:
n ≤ 20 n≤20n20

Two words sss andttt ifttt can be connected tossAfter s , then it must bettA certain suffix of t is equal tottA certain prefix of t , and the length of this equal part cannot be equal tomin ⁡ {ls, lt} \min\{l_s,l_t\}min { ls,lt} . In order to make the length of the solitaire longer, we must find the shortest suffix (for examples = "abcbc", andt = "bcbcd", then we must splice two"abcbcbcd"instead"abcbcd", the former only uses the overlapping part"bc"while the latter uses"bcbc"). We can first preprocess the shortest prefix and suffix length of each two strings that meet the above conditions, and then start enumerating the strings starting with "Dragon", and then DFS search. code show as below:

#include <iostream>
using namespace std;

const int N = 21;
int n;
string word[N];
// g[i][j]存word[i]和word[j]相等的最短前后缀长度(word[i]的后缀和word[j]的前缀),
// 如果不存在则赋值为0
int g[N][N];
// 存word[i]被用了多少次
int used[N];
// 存全局答案
int res;

// s是当前接龙的长度,cur存当前最新接到龙后面的单词下标
void dfs(string s, int cur) {
    
    
    res = max((int) s.size(), res);
    used[cur]++;

    for (int i = 0; i < n; i++)
        if (g[cur][i] && used[i] < 2)
            dfs(s + word[i].substr(g[cur][i]), i);

	// 回溯恢复现场
    used[cur]--;
}

int main() {
    
    
    cin >> n;
    for (int i = 0; i < n; i++) cin >> word[i];

    char st;
    cin >> st;

    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++) {
    
    
            string a = word[i], b = word[j];
            for (int k = 1; k < min(a.size(), b.size()); k++)
                if (a.substr(a.size() - k) == b.substr(0, k)) {
    
    
                    g[i][j] = k;
                    break;
                }
        }

    for (int i = 0; i < n; i++)
        if (word[i][0] == st)
            dfs(word[i], i);

    cout << res << endl;

    return 0;
}

The time complexity is related to the specific input, which can be regarded as exponential (or above), and the space complexity is O (n 2) O(n^2)O ( n2)

Guess you like

Origin blog.csdn.net/qq_46105170/article/details/114815615