題意 一個字元串被稱為容易串,指其中有相鄰的兩個相同的子串,反之為困難串。問你由前L個字元組成的字典序第k小的困難串。保證答案串長不超過80。
思路 難點在于如何判斷目前串是否為困難串,整串比較O(n^3),但如果用dfs,每次隻需要判斷新加入的字母會不會使字元串為困難串即可,通過枚舉不同長度的字尾即可,複雜度O(n^2)。是容易串就做可行性剪枝。
感覺這題非常适合dfs,整個就是為其設計的感覺,是入門dfs的好題~
#include <cstring>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <string>
using namespace std;
int n,l;
int cnt;
vector<char> vec;
bool judge()
{
if(vec.size() == 0)
return true;
int m = vec.size();
int i,j;
for(i=1;i<=m/2;i++)
{
for(j=0;j<i;j++)
{
if(vec[m-j-1] != vec[m-i-j-1])
{
break;
}
}
if(j >= i)
return false;
}
return true;
}
void out()
{
for(int i=0;i<vec.size();i++)
{
if(i%4 == 0 && i%64 != 0)
putchar(' ');
else if(i%64 == 0 && i != 0)
puts("");
printf("%c",vec[i]);
}
printf("\n%d\n",vec.size());
}
void dfs()
{
if(judge())
cnt++;
else
return;
if(cnt == n)
{
out();
return;
}
for(char i = 'A';i < 'A' + l;i++)
{
vec.push_back(i);
dfs();
if(cnt == n)
return;
vec.pop_back();
}
}
int main()
{
while(scanf("%d%d",&n,&l) == 2 && n)
{
cnt = -1;
vec.clear();
dfs();
}
return 0;
}