题目:如果一个字符串包含两个相邻的重复子串,则称它是”容易的串“,其他串成为”困难的串“。例如”ABCDABCD“是容易的串,而”ABDAB“是困难的串。
输入正整数n和L,输出由前L个字符组成的,字典序第n小的困难的串。
样例输入:7 3
30 3
样例输出:ABACABA
输入正整数n和L,输出由前L个字符组成的,字典序第n小的困难的串。
样例输入:7 3
30 3
样例输出:ABACABA
ABACABCACBABCABACABCACBACABA
分析:这题有三个难点:
第一个:如何判断两个相邻的重复子串?dfs第cur个位置时,表示前cur - 1个位置都以判断好,故只需判断第cur个字符与前cur - 1的关系
第二个:若碰到无解情况如何返回?设置dfs函数,找到解时返回0,否则返回1
第三个:cur并不能代表n,如何判断条件终止条件?设置变量cnt,每层递归就加1
#include <iostream>
#include <stdio.h>
using namespace std;
const int maxn = 80;
int n, l, cnt;
int s[maxn];
int dfs(int cur)
{
if (cnt++ >= n)
{
for (int i = 0; i < cur; ++i)
printf("%c", s[i] + 'A');
printf("\n");
return 0;
}
for (int i = 0; i < l; ++i)
{
s[cur] = i;
bool ok = true;
for (int j = 1; j <= (cur + 1) / 2; ++j)
{
bool equal = true;
for (int k = 0; k < j; ++k)
if (s[cur - k] != s[cur - k - j])
{
equal = false;
break;
}
if (equal)
{
ok = false;
break;
}
}
if (ok)
{
if (!dfs(cur + 1))
return 0;
}
}
return 1;
}
int main()
{
while (scanf("%d %d", &n, &l) == 2)
{
cnt = 0;
dfs(0);
}
}