個人在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;
}