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;
}
时间: 2024-10-29 04:23:01

HDU 1627 Krypton Factor的相关文章

hdu - 1627 Krypton Factor (dfs)

http://acm.hdu.edu.cn/showproblem.php?pid=1627 给定 n 和 L 找出第n个范围在0-L之内的字符串,字符串要求没有相邻的子串是相同的. 按照格式输出. 这个题的关键在于判断字符串是否是符合要求的字符串. 枚举字符串所有子串可能的长度,然后判断即可. #include <iostream> #include <cstdio> #include <cmath> #include <vector> #include

[2016-02-19][UVA][129][Krypton Factor]

UVA - 129 Krypton Factor Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu Submit Status Description You have been employed by the organisers of a Super Krypton Factor Contest in which contestants have very high mental and physica

Krypton Factor

Krypton Factor Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 181    Accepted Submission(s): 60 Problem Description You have been employed by the organisers of a Super Krypton Factor Contest in

UVA129 Krypton Factor

问题链接:UVA129 Krypton Factor. 问题简述:题目是氪因子.输入正整数n和L,输出由前L个字符组成的.字典顺序第n小的不含相邻重复字串的字符串.不含相邻重复字串的字符串是指,一个字符串中,任意两个相邻的字串都不相等.输出结果时,对于找到的字符串,每4个字符间加入一个空格,每行输出80个字符. 问题分析:回溯法实现.从第1个字符开始试探,每个字符从"A"开始可以是L个字符之一,直到遇见第n个满足条件的字符串.试探过程中,当前的串是不包含相邻相同子串的,所以只需要考虑加

hdu 2710 Max Factor(找最大素数)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2710 Problem Description To improve the organization of his farm, Farmer John labels each of his N (1 <= N <= 5,000) cows with a distinct serial number in the range 1..20,000. Unfortunately, he is unawa

uva129 - Krypton Factor 7.4.3 困难的串

  7.4.3困难的串 学习点:dfs加入返回值,递归搜索过程中如果有一个成功,就直接退出 //7.4.3 困难的串 #include<cstdio> #include<cstring> #include<iostream> #include<string> #include<algorithm> using namespace std; int n,L; int cnt; char v[81]; bool judge(int cur) { fo

【Uva 129】Krypton Factor(困难的串)

You have been employed by the organisers of a Super Krypton Factor Contest in which contestantshave very high mental and physical abilities. In one section of the contest the contestants are tested ontheir ability to recall a sequenace of characters

HDU 5428 The Factor 分解因式

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5428 The Factor Accepts: 101 Submissions: 811 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) 问题描述 有一个数列,FancyCoder沉迷于研究这个数列的乘积相关问题,但是它们的乘积往往非常大.幸运的是,FancyCoder只需要找到这个巨大

hdu 5428 The Factor(素数筛选合数分解)

题意:求一串数乘积的因子中的最小合数: 思路:比赛时枚举因子,枚举到两个时结束,估计超时,结果果然被叉了: 将每个数分解,取最小的两个质因子,若数目少于2,则不存在: #include<cstdio> #include<cstring> #include<vector> #include<algorithm> using namespace std; int t,n,m; int num[505]; const int MAXN=100000; int pr