zoukankan      html  css  js  c++  java
  • UVA129 Krypton Factor 困难的串 dfs回溯【DFS】

    

    Krypton Factor

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

    Total Submission(s): 392    Accepted Submission(s): 174
    Problem 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
    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 30 0
    Sample Output
    ABAC ABCA CBAB CABA CABC ACBA CABA28
    Source

    问题简介:

     输入正整数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;
    		
    		
    	}
    
    }
    




  • 相关阅读:
    Spring IOC(二)
    Spring组件注册
    第六章:随机数和expect
    第二十一节:异常处理
    第二十节:基础知识阶段复习
    LVM逻辑卷管理
    第十九节:类的装饰器和数据描述符的应用
    第十八节:上下文管理协议
    第十七节:数据描述符
    第十六节:内置函数补充
  • 原文地址:https://www.cnblogs.com/lingluan533/p/12537302.html
Copyright © 2011-2022 走看看