UVA 129困难的串【DFS】

题目链接

题目大意:

给出n,l;要求按特定格式输出由前l个大写字母构成的按字母表排列的第n个没有连续重复子串的字符串以及该字符串长度。

此题是一道dfs递归回溯的基础题,难点在于对当前字符串是否有连续重复子串的判断,具体做法是这样的,以长度为对象枚举以新添进字符为尾巴的子串,看是否重复。

但是我还是有一点疑问,为什么我将这段代码做出下列改动,就会Runtime error!

#include <cstdio>

int S[100];
int n, L, cnt;//cnt记录已经生成的合法字符串的个数 
 
int dfs(int cur)//cur记录S此时对应的字符串的长度                                 //改成void dfs(int cur)
{
    if (cnt++ == n)//完成搜索,输出结果并逐级结束函数调用 (返回0)
    {
        for (int i = 0; i < cur; ++i)
        {
            if (i % 64 == 0 && i) printf("
");             //注意这里要将i%64放在i%4的前面,优先换行
            else if (i % 4 == 0 && i) printf(" ");          //这里要用else if,防止输出下一行的时候,同时第一个位置为空格
            printf("%c", 'A' + S[i]);
        }//特定格式输出 
        printf("
%d
", cur);
        return 0;//函数调用结束                                                 //改成return;
    }
    for (int i = 0; i < L; ++i)//i从0开始,'A'+s[cur]从A开始 
    {
        S[cur] = i;
        int ok = 1;
        for (int j = 1; j * 2 <= cur + 1; ++j)//以长度为对象枚举以新添进字符为尾巴的子串,看是否重复。
        {
            int equal = 1;
            for (int k = 0; k < j; ++k)
                if (S[cur - k] != S[cur - k - j]) { equal = 0; break; }  //以j为长度枚举的相邻字串中,只要有任意一个字符与它对应位置的字符不相等,那么,以当前长度枚举的相邻子串就不相等         
            if (equal) { ok = 0; break; }
        }
        if (ok) if (!dfs(cur + 1)) return 0;                                   //将这里改成if(ok)dfs(cur+1);
    }
    return 1;                                                                  //将这里删去
}

int main()
{
    while (scanf("%d%d", &n, &L) == 2, n || L)
    {
        cnt = 0;//已找到合法字符串0个 
        dfs(0);//开始时S数组对应的字符串长度为0 
    }
    return 0;
}

2018-04-14

原文地址:https://www.cnblogs.com/00isok/p/8831768.html