zoukankan      html  css  js  c++  java
  • Krypton Factor 困难的串-Uva 129(回溯)

    原题:https://uva.onlinejudge.org/external/1/129.pdf

    按照字典顺序生成第n个“困难的串”

    “困难的串”指的是形如ABAB, ABCABC, CDFGZEFGZE的串,它们都有相邻的重复子字符串

    字母的范围是L,既 'A'到'A' + L


    分析: 大体上这是一道生成排列组合的题。难点在于我们如何判断当前生成的串是"困难的串"

    我们首先采用递归按照字典顺序从小到大生成串, 那么每一次我们处理的都是前一个"困难的串",

    既满足没有相邻重复子串。那么我们如何高效的判断给它新追加的字母会不会使它不满足"困难的串"的条件?


    判断方法

    如果最后一个字母等于倒数第二个字母,那么不是困难的串,返回false

    再从右往左找第一个和末尾字母相同的字母,因为它有可能是相邻重复串的末尾

    然后以找到的字母为中心点,判断左右两边串是不是相等,相等就返回false

    重复以上步骤

    所以算法时间复杂度是O(n^2)

    由于n <= 80

    所以完全够用

     1 #include <cstdio>
     2 #include <cstring>
     3 using namespace std;
     4 const int MAXN = 80 + 5;
     5 int sol[MAXN], L, n, cnt, depth;
     6 bool stop;
     7 
     8 bool check(int index, int chr) {
     9     if (index > 0) {
    10         if (chr == sol[index - 1]) return false;
    11         int i = index - 1;
    12         while (i >= 0) {
    13             while(i >= 0 && sol[i] != chr) i--;
    14             if (i >= 0 && sol[i] == chr && i * 2 + 1 >= index) {
    15                 bool same = 1;
    16                 for (int j = index - 1; j > i; j--)
    17                     if (sol[j] != sol[j - index + i]) same = 0;
    18                 if (same) return false;
    19             }
    20             i--;
    21         }
    22     }
    23     return true;
    24 }
    25 
    26 void next_str(int dep) {
    27     if (cnt == n) {
    28         stop = 1;
    29         for (int i = 0; i < dep; i++) {
    30             if (i && i % 64 == 0) putchar('
    ');
    31             else if (i && i % 4 == 0) putchar(' ');
    32             printf("%c", char(sol[i] + 'A'));
    33         }
    34         depth = dep;
    35         putchar('
    ');
    36         return;
    37     }
    38     for (int i = 0; i < L; i++) {
    39         if (stop) return;
    40         if (check(dep, i)) {
    41             sol[dep] = i;
    42             cnt++;
    43             next_str(dep + 1);
    44         }
    45     }
    46 }
    47 
    48 int main() {
    49     while (scanf("%d%d", &n, &L) == 2 && n) {
    50         stop = 0; cnt = depth = 0;
    51         next_str(0);
    52         printf("%d
    ", depth);
    53     }     
    54     return 0;
    55 }
  • 相关阅读:
    AQS笔记二 ---- 使用AQS自定义锁
    AQS笔记一 --- 源码分析
    ElasticSearch(二十一)正排和倒排索引
    ElasticSearch(二十)定位不合法的搜索及其原因
    ElasticSearch(十八)初识分词器
    ElasticSearch(十七)初识倒排索引
    还在用 kill -9 停机?这才是最优雅的姿势(转)
    一文快速搞懂MySQL InnoDB事务ACID实现原理(转)
    你真的理解零拷贝了吗?(转)
    关于分布式事务的读书笔记
  • 原文地址:https://www.cnblogs.com/Bowen-/p/4942194.html
Copyright © 2011-2022 走看看