问题描述:如果一个子妇产包含两个相邻的重复子串,则称它是“容易的串”,其他的串称为“困难的串”。例如,BB、ABCDACABCAB、ABCDABCD都是容易的,而D、DC、ABDAB、CBABCA都是困难的。输入一个正整数n和L,输出由前L个字符组成的、字典序第n小的困难的串。
解这个问题我用的是dfs,深度搜索,其实这个问题要枚举出各种排列并不是问题,有问题的是如何判断一个串里面到底有没有相邻且重复的子串,这才是问题的关键所在。
解过八皇后问题的童鞋都知道 ,在新放入一个皇后之后判断当前局面有没有冲突的时候,只需要判断当前局面有没有冲突,而不必去管以后的事,其实这个问题也一样,我们只要每次放进一个字符进去之后判它的每一种后缀你是否有相邻的并且相同的就可以了。然后如果判断出来没有冲突的话,就递归下去,直到找到第n个串。下面把代码贴出来看下:
1 #include<cstdio> 2 #include<cstring> 3 int num,L,n,A[1000]; 4 bool flag; 5 void dfs(int deep) { 6 if(flag) 7 return ; 8 if(num == n) { 9 flag = true; 10 for(int i = 0;i<deep;++i) 11 printf("%c",'A'+A[i]); 12 puts(""); 13 } 14 for(int i = 0;i<L;++i) { 15 A[deep] = i; 16 bool f = true; 17 for(int j = 1;j*2<=deep+1;++j) { 18 int k; 19 for(k = 0;k<j;++k) 20 if(A[deep-2*j+1+k] != A[deep-j+1+k]) 21 break; 22 if(k == j) { 23 f = false; 24 break; 25 } 26 } 27 if( f ) { 28 num++; 29 dfs(deep+1); 30 if(flag) 31 return ; 32 } 33 } 34 return ; 35 } 36 int main() { 37 while(scanf("%d%d",&n,&L)!=EOF) { 38 num = 0; 39 flag = false; 40 dfs(0); 41 } 42 return 0; 43 } 44 45