困难的串:
问题描述:如果一个字符串包含两个相邻的重复子串,则称它为容易的串,其他串称为困难的串,
如:BB,ABCDACABCAB,ABCDABCD都是容易的,A,AB,ABA,D,DC,ABDAB,CBABCBA都是困难的。
输入正整数n,L,输出由前L个字符(大写英文字母)组成的,字典序第n小的困难的串。
例如,当L=3时,前7个困难的串分别为:
A,AB,ABA,ABAC,ABACA,ABACAB,ABACABA
n指定为4的话,输出ABAC
思路:
由题目得知,困难的串是字符串中包含两个相邻的重复子串,我们写一个方法用来判断这个条件是否满足即可。
如果满足,则输出当前子串,计数加1,如果计数等于n的话,终止程序,不等于继续dfs值更新为当前子串。
如果不满足,说明当前尝试的字母不能和当前前缀字符串组成困难的串,那么就应该当前字母+1。
1 import java.util.Scanner; 2 3 public class Seven_17dfs困难的串 { 4 static int count = 0; 5 6 private static void dfs(int l, int n, String prefix) { 7 8 // 尝试在prefix后追加一个字符 9 for (char i = 'A'; i < 'A' + l; i++) { 10 if (isHard(prefix, i)) {// 是困难的串,就组合起来输出 11 String x = prefix + i; 12 System.out.println(x); 13 count++;// 计数 14 if (count == n) 15 System.exit(0); 16 17 dfs(l, n, x); 18 } 19 } 20 } 21 22 /** 23 * 判断prefix+i是否一个困难的串 1.遍历所有的长度为偶数的子串,看是否对称 2.prefix是一个困难的串 ABACA i 24 */ 25 private static boolean isHard(String prefix, char i) { 26 int wide = 0;// 截取的宽度 27 for (int j = prefix.length() - 1; j >= 0; j -= 2) { 28 final String s1 = prefix.substring(j, j + wide + 1); 29 final String s2 = prefix.substring(j + wide + 1) + i; 30 if (s1.equals(s2)) 31 return false; 32 wide++; 33 } 34 return true; 35 } 36 37 public static void main(String[] args) { 38 Scanner in = new Scanner(System.in); 39 int l = in.nextInt(); 40 int n = in.nextInt(); 41 42 dfs(l, n, ""); 43 } 44 }