题意:将一个包含两个相邻的重复子串的子串,称为“容易的串”,其他为“困难的串”。 输入正整数n和l,输出由前l个字符组成的,字典序第n小的困难的串。
输入样例:
7 3 30 3 0 0
输出样例
ABAC ABA 7 ABAC ABCA CBAB CABA CABC ACBA CABA 28
UVa的输入输出很烦。
1、每行最后无空格
2、每四个字母为一组,每组中间有一个空格,每十六组一行,第十七组在第二行输出(注意第一行最后不能有空格)
思路:搜索,判断后缀(因为前面的部分已经判断过)。
直接看代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
int cnt,n,l;
char a[1000];
int dfs(int cur){
if(cnt++ == n){
for(int i = 0; i < cur; i++){
printf("%c",a[i]);
if(i + 1 == 64&&i + 1!= cur)
printf("
");
else
if((i + 1)%4 == 0&&i + 1!= cur)printf(" ");
}
printf("
%d
",cur );
return 0;//返回0代表已经找到第n大的困难的串
}
for(int i = 0; i < l; i++){//
a[cur] = i + 'A';
int ok = 1;
for(int j = 1; j*2 <= cur + 1; j++){//j是后缀长度
int is_same = 1;
for(int k = 0; k < j; k++){
if(a[cur - k] != a[cur - j - k]){//依次比较各个字母
is_same = 0;
break;
}
}
if(is_same){
ok = 0;
break;
}
}
if(ok)if(!dfs(cur + 1))return 0;
}
return 1;
}
int main(){
while((cin >> n >> l)&&(n|l)){//特判n==0的情况
cnt = 0;
dfs(0);
}
return 0;
}