dfs回溯。判断后缀很重要。
/*Input
Each input line contains integers n and L (in that order), where n > 0 and L is in the range 1 ≤ L ≤ 26.
Input is terminated by a line containing two zeroes.
Output
For each input line prints out the n-th hard sequence (composed of letters drawn from the first L letters
in the alphabet), in increasing alphabetical order (Alphabetical ordering here corresponds to the normal
ordering encountered in a dictionary), followed (on the next line) by the length of that sequence. The
first sequence in this ordering is ‘A’. You may assume that for given n and L there do exist at least n
hard sequences.
As such a sequence is potentially very long, split it into groups of four (4) characters separated by
a space. If there are more than 16 such groups, please start a new line for the 17th group.
Your program may assume a maximum sequence length of 80.
For example, with L = 3, the first 7 hard sequences are:
A
AB
ABA
ABAC
ABACA
ABACAB
ABACABA
Sample Input
7 3
30 3
0 0
Sample Output
ABAC ABA
7
ABAC ABCA CBAB CABA CABC ACBA CABA
28*/
#include <bits/stdc++.h>
using namespace std;
int cnt;
int n,l,s[85];
int dfs(int cur)
{
if(cnt++==n)
{
int i;
for( i=0;i<cur;i++)
{
if(i&&i%64!=0&&i%4==0)
cout<<" ";
if(i&&i%64==0)
cout<<endl;
cout<<(char)(s[i]+'A');
}
cout<<endl<<i<<endl;
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)//尝试长度为j*2的后缀。
{
int equal=1;
for(int k=0;k<j;k++)
{
if(s[cur-k]!=s[cur-j-k])
{
equal=0;
break;
}
}
if(equal){ok=0;break;}
}
if(ok)
if(!dfs(cur+1))return 0;
}
}
return 1;
}
int main()
{
while(cin>>n>>l&&n&&l)
{
cnt=0;
dfs(0);
}
return 0;
}