标签:回溯法
1.题目描述:点击打开链接
2.解题思路:本题利用回溯法解决。根据题意描述,易知在枚举第cur位时,只用检查它添加后该串是否合法,而不必去检查cur之间的串是否合法,因为这一步检查在枚举cur之前早已经做过了。另外,本题的输出比较坑,需要小心。
3.代码:
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<string>
#include<sstream>
#include<set>
#include<vector>
#include<stack>
#include<map>
#include<queue>
#include<deque>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#include<functional>
using namespace std;
#define N 80+10
int S[N];
int n, L;
int cnt;
int dfs(int cur)
{
if (cnt++ == n)
{
for (int i = 0; i < cur; i++)
{
printf("%c", 'A' + S[i]);
if ((i + 1) % 4 == 0)
{
if ((i + 1) % 64 == 0)cout << endl;
else if (i != cur - 1)putchar(' ');
}
}
if (cur % 64)cout << endl;
printf("%d\n", cur);
return 0;//返回0表示已经找到了解
}
for (int i = 0; i < L; i++)
{
S[cur] = i;
int ok = 1;
for (int j = 1; j * 2 <= cur + 1; j++)//枚举后缀的长度(注意不是整个串的长度)
{
int equal = 1;
for (int k = 0; k < j;k++)//检查前缀和后缀是否相等,S[cur-k]是后缀部分,S[cur-k-j]是前缀部分
if (S[cur - k] != S[cur - k - j]){ equal = 0; break; }
if (equal){ ok = 0; break; }
}
if (ok)if (!dfs(cur + 1))return 0;//如果找到解,直接退出
}
return 1;
}
int main()
{
//freopen("t.txt", "r", stdin);
while (~scanf("%d%d", &n, &L)&&(n||L))
{
cnt = 0;
memset(S, 0, sizeof(S));
dfs(0);
}
return 0;
}标签:回溯法
原文地址:http://blog.csdn.net/u014800748/article/details/44891851