例题7-5 困难的串(Krypton Factor, UVa 129)

欢迎访问我的Uva题解目录哦 https://blog.csdn.net/richenyunqi/article/details/81149109

题目描述

例题7-5 困难的串(Krypton Factor, UVa 129)题目描述

题意解析

如果一个字符串包含两个相邻的重复子串,则称它是“容易的串”,其他串称为“困难的串”。例如,BB、ABCDACABCAB、ABCDABCD都是容易的串,而D、DC、ABDAB、CBABCBA都是困难的串。
输入正整数n和L,输出由前L个字符组成的、字典序第k小的困难的串。例如,当L=3时,前7个困难的串分别为A、AB、ABA、ABAC、ABACA、ABACAB、ABACABA。输入保证答案不超过80个字符。

算法设计

从左到右依次考虑每个位置上的字符。判断当前字符串是否已经存在连续的重复子串。判断方法是:在字符串中从后向前查找与最新加入的字符相同的字符,并查看以最新加入的字符和查找到的字符结尾的字符串是否相同,如果相同说明出现了重复的子串,那么就不符合要求,删去最新加入的字符,继续进行枚举,直到没有重复的子串。

C++代码

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

猜你喜欢

转载自blog.csdn.net/richenyunqi/article/details/100691541
129
今日推荐