首页 > 代码库 > 困难的串(dfs)

困难的串(dfs)

                        困难的串

  题意:

  如果一个字符串包含两个相邻的重复子串,则称它是“容易的串”,其他串称为“困难的串”。例如,                 BB、ABCDABCD都是容易的串,而D、DC、ABDAD、CBABCBA都是困难的串。

  输入正整数n和L,输出由前L个字符组成的、字典序第k个困难的串。例如,当L=3时,前7个困难的串          分别为A、AB、ABA、ABAC、ABACA、ABACAB、ABACABA。输入保证答案不超过80个字符。

  样例输入:

      7  3

  30 3

  样例输出:

  ABACABA

  ABACABCACBABCABACABCACBACABA

  思路:构建一个字符串a[],往其中不断增加满足条件的字符,直至字符串大小为n,即为所求字符串;

假设当前串长度为cur,则字符串a[cur-1]的所有子串都是困难的,所以只需判断字符串a[cur]是否困难即可;

  代码:

#include <bits/stdc++.h>
#define MAXN 100
using namespace std;

int a[MAXN], n, l, cnt=0;

int dfs(int cur)
{
    if(cnt++==n)    //**每当cnt+1必能增加一个合法字符,当cnt=n时即得到所求字符串
    {
        for(int i=0; i<n; i++)
        {
            printf("%c", a[i]+‘A‘);
        }
        printf("\n");
        return 0;
    }
    for(int i=0; i<l; i++)
    {
        a[cur]=i;              //****尝试选中字符i+"A"
        int flag=1;
        for(int j=1; j*2<=cur+1; j++)   //***当前构建长度为2*j的字符串
        {
            int k;
            for(k=0; k<j; k++)      //***判断当前字符串是否是容易的串
            {
                if(a[cur-k]!=a[cur-k-j])
                {
                    break;        
                }
            }
            if(k==j)  //***如果k=j,即其为容易的串
            {
                flag=0;
                break;
            }
        }
        if(flag)  //***如果当前串为困难的串,并且cnt!=n,继续递归,如果cnt=n,递归结束,直接退出
        {
            if(!dfs(cur+1))
            {
                return 0;
            }
        }
    }
    return 1;
}

int main(void)
{
    std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    cin >> n >> l;
    dfs(0);
    return 0;
}

  

困难的串(dfs)