zoukankan      html  css  js  c++  java
  • HDU 1627 Krypton Factor

    回溯法:避免无用判断,强化回溯代码的实现过程

    题目的大意就是以字典序为准,排列字符串,但要保证一个字符串中不包含相邻的重复子串

    Problem Description

    For example, the sequence ABACBCBAD is easy, since it contains an adjoining repetition of the subsequence CB. Other examples of easy sequences are:

    BB
    ABCDACABCAB
    ABCDABCD

    Some examples of hard sequences are:

    D
    DC
    ABDAB
    CBABCBA

     

     

    Input

    In order to provide the Quiz Master with a potentially unlimited source of questions you are asked to write a program that will read input lines that contain integers n and L (in that order), where n > 0 and L is in the range , and for each input line prints out the nth hard sequence (composed of letters drawn from the first L letters in the alphabet), in increasing alphabetical order (alphabetical ordering here corresponds to the normal ordering encountered in a dictionary), followed (on the next line) by the length of that sequence. The first sequence in this ordering is A. You may assume that for given n and L there do exist at least n hard sequences.

    For example, with L = 3, the first 7 hard sequences are:

    A
    AB
    ABA
    ABAC
    ABACA
    ABACAB
    ABACABA
    As each sequence is potentially very long, split it into groups of four (4) characters separated by a space. If there are more than 16 such groups, please start a new line for the 17th group.

    Therefore, if the integers 7 and 3 appear on an input line, the output lines produced should be


    ABAC ABA
    7
    Input is terminated by a line containing two zeroes. Your program may assume a maximum sequence length of 80.

     

     

    Sample Input

    30 3

    0 0

     

     

    Sample Output

    ABAC ABCA CBAB CABA CABC ACBA CABA

    28

     

    在判断当前字符串是否已经存在连续的重复子串,例如判断ABACABA是否包含连续重复子串,并不需要说检查该字符串所有长度为偶数的子串,仅需要做的是判断当前串的后缀。

    另外对回溯法来说,一旦本次所要赋值的字符不满足,并且在循环了所有可以在这一次赋值的字符后,仍未满足,就要回溯到上一层,这种情况首先要保证成功次数不要增加(可以将次数设置为全局变量,当然进行完这一组数据后,要记得重新赋值,避免后面的测试数据出现问题,通常全局变量都要在完成一组数据测试后,重新赋初始值)

    代码如下

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define MAXN 200
    using namespace std;
    char alp[MAXN]="AABCDEFGHIJKLMNOPQRSTUVWXYZ";//首先打表方便后面的操作
    char ch[MAXN]="#";//处理一个小的细节,当第一个字符时,其实不需要判断前面的字符,为了统一操作,在ch[0]处赋一个与第一个字符一定不同的量
    int c=0;
    bool tag=false;//全局变量,完成字符串的标志
    void dfs(int n,int t,int cur)
    {
        int i,j,k=1,m,s;
        bool flag=true;
        if(n==c)//以次数作为完成的标志
        {
            while(k<=cur-1)
            {
                if(k==65)
                    cout<<endl;
                if(k%4==0&&k!=64&&k!=cur-1)//处理格式要求
                    cout<<ch[k]<<' ';
                else
                    cout<<ch[k];
                k++;
            }
            cout<<endl;
            cout<<cur-1<<endl;
            tag=true;//以标示符作为字符串完成的标志
        }
        else
        {
            for(i=1;i<=t;i++)//循环此次可以赋值的字符
            {
                flag=true;
                ch[cur]=alp[i];
                for(j=cur/2;j<=cur-1;j++)//字符串判重
                {
                    s=0;
                    m=cur-j-1;
                    for(k=0;k<=m;k++)
                    {
                        if(ch[cur-k]==ch[j-k])
                            s++;
                    }
                    if(s==m+1)
                    {
                        flag=false;
                        break;
                    }
                }
                if(flag==false)
                    continue;
                if(!tag)
                {
                    c++;
                    dfs(n,t,cur+1);//满足,则字符的长度加一,这也满足字典序的要求,若回溯到这里,那么即回头继续循环可以满足的字符,相当于说字符长度加一个不满足,那么前一个字符往后改,就如同从ABC->ABD(原本要走ABCD的)
                }
                if(tag)
                {
                  //  cout<<"return ";
                    return ;//若已完成则一步步回头
                }
            }
        }
    }
    int main()
    {
        int n,l;
        while(cin>>n>>l)
        {
            if(n==0&&l==0)
                break;
            else
                dfs(n,l,1);
            tag=false;//全局变量重新赋初始值
            c=0;// 全局变量重新赋初始值
        }
        return 0;
    }
  • 相关阅读:
    hdu acm 2639背包问题,这题很经典啊~~~
    hdu acm 2191
    qt中实现区域反白效果
    解决pythonxml 模块 在ubuntu karmic中找不到的问题
    Python正则表达式操作指南
    webkit 资料
    标点符号的英语名称
    ubuntu设置分辨率
    如何绑定多个action到一个slot
    改注册表,实现像迅雷一样的自定义url
  • 原文地址:https://www.cnblogs.com/fancy-itlife/p/4297090.html
Copyright © 2011-2022 走看看