个人在UVa上写题的感觉就是先WA, 后PE好多次,最后才AC的。但是还是莫名的喜欢这个OJ吧!!!
/*
题目大意:寻找第n个困难的串,困难的串中所含的字母个数为L个
困难的串指的是整个字符串中没有出现连续相同子串的字符串
*/
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#define MAXN 110
using namespace std;
int n, L;//第n个困难的串,和含有L个字母
int step;//step指的是当前是第step个困难的串
int arge[MAXN];//先用数字储存,后用'A'+数字表示字母
int dfs(int cur)
{//这里的cur指的是当前困难的串所包含的字符数,这里值得注意的是cur和step不相同,step是第几个困难的串。
if (step++ == n)
{//每次经过这里,就说明上一个字符是困难的串,所以step++,倘若它已经是第step个,那就++
for (int i = 1; i < cur; i++)
{//用正确的格式输出这第step个字符串
putchar('A' + arge[i]);
if (i % (4 * 16) == 0)
putchar('\n');
else if (i % 4 == 0 && i != cur - 1)
putchar(' ');
}
putchar('\n');
printf("%d\n", cur - 1);
return true;//返回true代表找到了
}
else
for (int i = 0; i < L; i++)
{//依次尝试L个字符
bool flag = true;//如果最后的字符是'A'+i它是否是困难的串
arge[cur] = i;
for (int j = 1; j * 2 <= cur; j++)//用来列举偶数后缀
{
bool ok = true;//判断当前后缀是否困难的串
for (int k = 0; k < j; k++)
{//检查后缀
if (arge[cur - k] != arge[cur - k - j])
{
ok = false;//如果有一个子串不是困难的串,那它整个串就不会是困难的串
break;
}
}
if (ok)
{
flag = false;//该串不是困难的串
break;
}
}
if (flag)
if (dfs(cur + 1))//如果已经找到了第step个困难的串就返回true
return true;
}
return false;//如果没找到就返回false,这步忘了会无限的递归,到没有结果
}
int main(void)
{
while (scanf("%d%d", &n, &L) != EOF && n + L)
{
step = 0;
memset(arge, 0, sizeof(arge));
dfs(1);
}
return 0;
}