zoukankan      html  css  js  c++  java
  • UVa 129

    题目描述:

    image-20201220184552977

    image-20201220184621482

    代码:

    int dfs(int cur)
    {
        if (cnt++ == n)
        {
            for (int i = 0; i < cur; i++)
            {
                printf("%c", 'A' + S[i]); // 输出方案
            }
            printf("
    ");
            return 0;
        }
        for (int i = 0; i < L; i++)
        {
            S[cur] = i;
            int ok = 1;
            for (int j = 1; j * 2 <= cur + 1; j++)
            { // 尝试长度为 j * 2 的后缀
                int equal = 1;
                for (int k = 0; k < j; k++)
                {
                    if (S[cur - k] != S[cur - k - j])
                    {
                        equal = 0;
                        break;
                    }
                }
                if (equal)
                {
                    ok = 0;
                    break;
                }
            }
            if (ok)
            {
                if (!dfs(cur + 1))
                { // 递归搜索。如果已经找到解,则直接退出
                    return 0;
                }
            }
        }
        return 1;
    }
    

    关于

    for (int j = 1; j * 2 <= cur + 1; j++)
    { // 尝试长度为 j * 2 的后缀
        int equal = 1;
        for (int k = 0; k < j; k++)
        {
            if (S[cur - k] != S[cur - k - j])
            {
                equal = 0;
                break;
            }
        }
        if (equal)
        {
            ok = 0;
            break;
        }
    }
    

    的说明:

    当递归到了 cur 时,从后往前尝试是否有相邻的重复的字串。j 从 1 开始,然后到 (displaystyle frac{cur + 1}{2}) 结束,先从右往左探测长度为 1 的相邻字串是否是重复的,然后探测长度为 2 的...

    Q:为什么只需要从当前项 cur 开始探测呢,需要以 cur 的前一项为起点进行探测吗?

    A:因为去掉 cur 的字串是困难的串,所以我们只需要以 cur 为起点进行探测就好了。这里,我们省去了很多无用功,因为我们只需要判断当前串的后缀,而非所有的字串。

    完整测试代码:

    #include <iostream>
    
    int cnt = 0; // 计数器
    int n = 0;
    int L = 0;
    int S[80] = {0};
    
    int dfs(int cur)
    {
        if (cnt++ == n)
        {
            for (int i = 0; i < cur; i++)
            {
                printf("%c", 'A' + S[i]); // 输出方案
            }
            printf("
    ");
            return 0;
        }
        for (int i = 0; i < L; i++)
        {
            S[cur] = i;
            int ok = 1;
            for (int j = 1; j * 2 <= cur + 1; j++)
            { // 尝试长度为 j * 2 的后缀
                int equal = 1;
                for (int k = 0; k < j; k++)
                {
                    if (S[cur - k] != S[cur - k - j])
                    {
                        equal = 0;
                        break;
                    }
                }
                if (equal)
                {
                    ok = 0;
                    break;
                }
            }
            if (ok)
            {
                if (!dfs(cur + 1))
                { // 递归搜索。如果已经找到解,则直接退出
                    return 0;
                }
            }
        }
        return 1;
    }
    
    
    int main()
    {
        n = 30;
        L = 3;
        dfs(0);
        return 0;
    }
    

    测试 n = 7,L = 3 和 n = 30,L = 3 的输出分别为:

    ABACABA

    ABACABCACBABCABACABCACBACABA

  • 相关阅读:
    福大软工1816 · 第四次作业
    福大软工1816 · 第三次作业
    福大软工1816 · 第二次作业
    福大软工1816 · 第四次作业
    福大软工1816 · 第三次作业
    Alpha 冲刺 (4/10)
    Alpha 冲刺 (3/10)
    Alpha 冲刺 (2/10)
    Alpha 冲刺 (1/10)
    项目需求分析
  • 原文地址:https://www.cnblogs.com/fanlumaster/p/14164521.html
Copyright © 2011-2022 走看看