天天看點

UVa129 - Krypton Factor 不錯的DFS入門題

題意 一個字元串被稱為容易串,指其中有相鄰的兩個相同的子串,反之為困難串。問你由前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;
}