如果一个字符串包含两个相邻重复的子串,则称它是容易的串,如果不含这样的串就称为困难的串。例如:BB,ABCDACABCAB,ABCDABCD都是容易的串,而D,DC,ABDAB,CBABCBA都是困难的串。
输入整数n和 l,输出由前 l 个字符串组成的,字典序为第n小的困难的串,例如,当l=3时,前7个困难的串分别为:A,AB,ABA,ABAC,ABACA,ABACAB,ABACABA输入保证答案不超过80个字符。
Sample:
input:
7 3
30 3
output:
ABACABA
ABACABCACBABCABCABCACBACABA
题意也就要我么寻找第n字典序的由前l 个字母组成的困难的串。
每次都要从字母A开始遍历,这是必要的,因为这样才能保证字典序最小。
每次在前l 个字母中向字符串中添加一个字母都要回去检查是否出现了相邻的重复的串,如果没有出现就继续向下找再添加。
代码及详解如下:
1 #include<iostream> 2 #include<cstring> 3 using namespace std; 4 int n,l; 5 int s[100]; 6 bool find2; 7 void dfs(int cur)//initial by zero 8 { 9 if(cur==n)//当达到第n个的时候停止 10 { 11 for(int i=0;i<cur;i++) 12 printf("%c",s[i]+'A'); 13 printf(" "); 14 find2=true; 15 return; 16 } 17 for(int i=0;i<l;i++) 18 { 19 s[cur]=i; 20 int ok=1; 21 for(int j=1;j*2<=cur+1;j++) 22 { 23 int equal=1; 24 for(int k=0;k<j;k++) 25 if(s[cur-k]!=s[cur-k-j]){//从最后一个字符串开始向前对比,是否出现重复 26 //例如字符串为:123456789,后面新加一个0,成为1234567890,开始对比 27 //0和9位置上地字符是否相等,然后判断90组成的子字符串和78组成的字符串 28 //是否相等,判断890和567位置上的子字符串是否相同 29 //直到判断67890和12345对比,然后终止,如果否和要求继续向下添加。 30 equal=0;break; 31 } 32 if(equal){ 33 ok=0; 34 break; 35 } 36 } 37 if(ok){ 38 dfs(cur+1); 39 if(find2)return; 40 } 41 } 42 return; 43 } 44 int main() 45 { 46 while(cin>>n>>l) 47 { 48 memset(s,0,sizeof(s)); 49 find2=false; 50 dfs(0); 51 } 52 return 0; 53 }