UVA129 Krypton Factor 困难的串 dfs回溯【DFS】
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 392 Accepted Submission(s): 174Problem Description
You have been employed by the organisers of a Super Krypton Factor Contest in which contestants have very high mental and physical abilities. In one section of the contest the contestants are tested on their ability to recall a sequenace of characters which has been read to them by the Quiz Master. Many of the contestants are very good at recognising patterns. Therefore, in order to add some difficulty to this test, the organisers have decided that sequences containing certain types of repeated subsequences should not be used. However, they do not wish to remove all subsequences that are repeated, since in that case no single character could be repeated. This in itself would make the problem too easy for the contestants. Instead it is decided to eliminate all sequences containing an occurrence of two adjoining identical subsequences. Sequences containing such an occurrence will be called ``easy''. Other sequences will be called ``hard''.
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
InputFor 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
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 InputFor 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.
30 30 0
ABAC ABCA CBAB CABA CABC ACBA CABA28
问题简介:
输入正整数n和L,输出由前L个字符组成的、字典顺序第n小的不含相邻重复字串的字符串。不含相邻重复字串的字符串是指,一个字符串中,任意两个相邻的字串都不相等。输出结果时,对于找到的字符串,每4个字符间加入一个空格,每行输出80个字符。
思路分析:
大致的框架就是每次增加一个字符,在增加字符的同时去判断加上这个字符后是否产生了连续的相同子串,这也是很关键的一个点,如何判断是否产生了连续的相同子串,由于采用了回溯的思想,故以前的串是没有连续的相同子串的,故只需从后向前看包含了新字母后有无连续的相同子串。我们可以外层循环去遍历两个子串的长度,从1-(cur+1)/2(即当前串的一半),内层循环去遍历每一对子串的对应的点,如果在内层循环找到了一个点在两个子串上的对应位置不相等,则在此长度下没有产生连续的相同子串。于是,外层循环的长度加1,去判断下一个子串是否相同。如果找到了某一对连续的相同子串,则此次的分配不合理,尝试在该点分配下一个小于L的字母,如果没有找到一对连续的相同子串,则此次分配合理,可以递归下一个点,并且记录困难子串的变量加一。当变量等于n的时候则输出该序列即可。 由于无需返回值,所以直接return 即可。
package lianxi;
import java.util.Scanner;
public class KryptonFactorUva129 {
static Scanner scan = new Scanner(System.in);
static int C[]=new int [10000];
static int n,l,count=0;
public static void main(String[] args) {
while(scan.hasNext()){
n = scan.nextInt();
l = scan.nextInt();
getFactor(0);
for(int i=0;i<C.length;i++){
C[i] = 0;
}
}
}
private static int getFactor(int cur) {
if(count++ == n){
for(int i = 0;i<cur;i++){
System.out.print((char)(C[i]+'A'));
}
System.out.println();
return 0;
}
for(int i=0;i<l;i++){
C[cur] = i;
int ok = 1;
for(int j = 1;j*2<=cur+1;j++){
int equal = 1;
for(int k = 0;k < j;k++){
if(C[cur - k] != C[cur-k-j] ){
equal = 0; //找到一个不相同的点本次的测试子段即为困难的串
break;
}
}
if(equal == 1){
ok = 0;
break; //存在了相同的连续子串,尝试下一个字母
}
}
if(ok==1){
if(getFactor(cur+1) == 0){
return 0;
}
}
}
return 1;
}
}