UVa 129 Krypton Factor (DFS && 回溯)

题意 : 如果一个字符串包含两个相邻的重复子串,则称它是“容易的串”,其他串称为“困难的 串”。例如,BB、ABCDACABCAB、ABCDABCD都是容易的串,而D、DC、ABDAB、 CBABCBA都是困难的串。程序从输入中读取多行数据,每行包括两个整数n和L(即按此顺序给出),其中n > 0,L的范围是1 ≤ L ≤ 26。根据这些输入,程序要按照字母表升序打印出第n个“hard”字串(由字母表中的前L个字母构成),并在接下来的一行打印这个串的长度。按照上述规则,第一个串应该是“A”。对于给定的n和L,保证第n个“hard”串是一定存在的。比方说,当L = 3时,头7个“hard”字串为:

A
AB
ABA
ABAC
ABACA
ABACAB
ABACABA

分析 : 考虑使用深搜暴力一个个构造出合法的困难串,在深搜时按字典序考虑构造序列的每一位即可。但是有个难点,就是如何判断是否有重复?紫书给出了很好的解释=》一种方法是检查所有长度为偶数的子串,分别判断每个字串的前一半是否等于后 一半。尽管是正确的,但这个方法做了很多无用功。还记得八皇后问题中是怎么判断合法性 的吗?判断当前皇后是否和前面的皇后冲突,但并不判断以前的皇后是否相互冲突——那些 皇后在以前已经判断过了。同样的道理,我们只需要判断当前串的后缀,而非所有子串。换句话说就是在每判断一个位置的时候,我们只要枚举并检查含有新添加字母的偶数串合法后缀(也就是串的长度不要超过总长),就像书上说的,因为是一个个字母递增添加构造的,所以每一个都有和前面的进行判断,故只考虑当前而不考虑之前。

#include<bits/stdc++.h>
using namespace std;
int k, L;
char * letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int ans;
bool check(char *temp, int last)
{
    for(int j=1; 2*j<=last+1; j++){//->learn
        bool Equal = true;
        for(int k=0; k<j; k++){
            if(temp[last-j+1+k] != temp[last-2*j+1+k]) {Equal = false;break;}
            //if(temp[last-k] != temp[last-k-j]) {Equal = false;break;}//也可以
        }
        if(Equal) return false;
    }
    return true;
}
int cnt = 0;
inline void DFS(int num, char *temp)
{
    if(ans!=-1) return ;
    if(cnt==k) { temp[num]=‘\0‘;ans=strlen(temp);return ; }
    for(int i=0; i<L; i++){
        if(ans!=-1) return ;
        temp[num] = letter[i];
        if(check(temp, num)){
            cnt++;
            DFS(num+1, temp);
        }
    }
}
int main(void)
{
//    freopen("in.txt", "r", stdin);
//    freopen("out.txt", "w", stdout);
    while(~scanf("%d %d", &k, &L) && (k&&L)){
        ans = -1, cnt = 0;
        char temp[82];
        DFS(0, temp);
        int blank = 0;
        int tot_group = 0;
        for(int i=0; i<ans; i++){
            if(i != 0 && i % 64 == 0)
                printf("\n");
            else if(i != 0 && i % 4 == 0)
                printf(" ");
            printf("%c", temp[i]);
        }
        printf("\n%d\n", ans);
    }
    return 0;
}

瞎想 : 在考虑八皇后或此类深搜回溯进行构造的时候,如果需要有一些结合前面判断状态是否可行,那就多想想是否只考虑构成当前状态的新因素和已构造出的东西就可以判断状态是否可行,因为此类一个个递增构造的,每构造一个状态出来就要判别一次,当前状态的判别就不用理会之前的状态了,因为在做重复工作。

时间: 2024-10-28 11:23:01

UVa 129 Krypton Factor (DFS && 回溯)的相关文章

UVa 129 Krypton Factor【回溯】

学习的紫书的回溯,理解起来还是好困难的说啊= = 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include <cmath> 5 #include<stack> 6 #include<vector> 7 #include<map> 8 #include<set> 9 #include<queue> 10 #includ

[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

Uva 129 Krypton Factor

0.这道题的输出 处理起来挺麻烦的 以后类似的可以借鉴一下 for(int i=0;i<cur;i++) { if(i!=0 && i%64==0) printf("\n%c",a[i]); else if(i!=0 && i%4==0) printf(" %c",a[i]); else printf("%c",a[i]); } 1.还有一个是输出 第n小  怎么来控制第n小   利用的是一个初始化为0的cn

uva 11218 KTV(DFS+回溯)

uva 11218 KTV One song is extremely popular recently, so you and your friends decided to sing it in KTV. The song has 3 characters, so exactly 3 people should sing together each time (yes, there are 3 microphones in the room). There are exactly 9 peo

129 - Krypton Factor(dfs回溯)

回溯法的再次利用,体会精妙之处. 多研究,多做题~~ #include<bits/stdc++.h> using namespace std; int n,L,cnt,s[100]; int dfs(int cur) { if(cnt++==n) { int kase=0,ans=0,ens=0; for(int i=0;i<cur;i++){ printf("%c",'A'+s[i]); kase++; ens++; if(kase==4) { kase=0; an

UVA-129 Krypton Factor(回溯)

题目大意:由字母A到Z组成的字符串,其中有两个子串完全相同的叫做容易的串,反之叫困难的串.找出由前L个字母组成的第n个困难的串. 题目分析:简单回溯,不过要判断是否存在重复子串比较棘手.<入门经典>上借鉴八皇后问题,只判断添进字符后是否存在连续子串.具体做法是这样的,以长度为对象枚举以新添进字符为尾巴的子串,看是否重复. 代码如下: # include<iostream> # include<cstdio> # include<cstring> # incl

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

【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

UVA 23 Out of 5(DFS+回溯)

Problem I 23 Out of 5 Input: standard input Output: standard output Time Limit: 1 second Memory Limit: 32 MB Your task is to write a program that can decide whether you can find an arithmetic expression consisting of five given numbers (1<=i<=5) tha