书上的例题,简单回溯题,要点是只需要判断当前串的后缀,而非所有子串
#include<iostream>
#include<cstring>
#include<cctype>
#include<cstdio>
#include<map>
#include<set>
#include<list>
#include<cstdlib>
#include<string>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
using namespace std;
int n,l;
int cnt;
int s[85];
int dfs(int cur)//cur记录字符个数
{
if(cnt++ == n)//cnt记录第几个hard sequence
{
int num = 0;
for(int i = 0; i < cur; ++i)
{
if(i%64==0 && i) printf("\n"); //若16组后要先换行
else if(i%4==0 && i) printf(" "); //每4个用空格隔开
printf("%c",s[i]+'A');
}
printf("\n%d\n",cur);
return 0;
}
else for(int i = 0; i < l; ++i)
{
s[cur] = i;
int ok = 1;
for(int j = 1; j*2 <= cur+1; ++j)
{
int equ = 1;
for(int k = 0; k < j; ++k)
//这里是重点,每次循环检查长度为2*j的后缀,即k = 1到j.
if(s[cur-k] != s[cur-k-j]) {equ = 0; break;}
if(equ) {ok = 0; break;}
}
if(ok) if(!dfs(cur+1)) return 0;
}
return 1;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif // ONLINE_JUDGE
while(scanf("%d%d",&n,&l) == 2)
{
if(n == 0 && l == 0) break;
cnt = 0;
dfs(0);
}
return 0;
}