Example 7-5 The difficult string (Krypton Factor, UVa 129)

Welcome to visit my Uva problem solution directory https://blog.csdn.net/richenyunqi/article/details/81149109

Title description

Example 7-5: Krypton Factor (UVa 129) problem description

Interpretation

If a string contains two adjacent repeated substrings, it is called an "easy string", and the other strings are called a "difficult string". For example, BB, ABCDACABCAB, ABCDABCD are all easy strings, while D, DC, ABDAB, and CBABCBA are all difficult strings.
Input positive integers n and L, and output the k-th smallest lexicographically difficult string consisting of the first L characters. For example, when L=3, the first 7 difficult strings are A, AB, ABA, ABAC, ABACA, ABACAB, ABACABA. Enter to ensure that the answer does not exceed 80 characters.

algorithm design

Consider the characters at each position in turn from left to right. Determine whether the current string has continuous repeated substrings. The judgment method is: search for the same character as the newly added character in the string from back to front, and check whether the character string ending with the newly added character and the character found is the same. If the same, it means that there is a repeated substring. , Then it does not meet the requirements, delete the newly added characters, and continue to enumerate until there are no repeated substrings.

C++ code

#include <bits/stdc++.h>
using namespace std;
int n, l;
bool f(string& s) {
    
    //回溯
    if (n == 0)//n为0时表示找到了结果,返回true
        return true;
    for (int i = 0; i < l; ++i) {
    
    //枚举'A'到'A'+L字符
        s += 'A' + i;
        //从后向前查找与最新加入的字符相同的字符
        for (int j = s.rfind('A' + i, s.size() - 2); j >= s.size() - 2 - j && j != string::npos; j = s.rfind('A' + i, j - 1))
            if (s.substr(j + 1) == s.substr(j + j + 2 - s.size(), s.size() - 1 - j))//出现了重复的子串
                goto loop;//删去最后的字符
        --n;
        if (f(s))//处理下个位置
            return true;
    loop:
        s.pop_back();
    }
    return false;
}
int main() {
    
    
    while (cin >> n >> l && n != 0) {
    
    
        string s = "";
        f(s);
        for (int i = 0, group = 0; i < s.size(); ++i) {
    
    //group表示组号
            if (i != 0 && i % 4 == 0)
                putchar((++group) % 16 == 0 ? '\n' : ' ');
            putchar(s[i]);
        }
        printf("\n%d\n", s.size());
    }
    return 0;
}

Guess you like

Origin blog.csdn.net/richenyunqi/article/details/100691541