UVA.129 Krypton Factor (搜索+暴力)
UVA.129 Krypton Factor (搜索+暴力)
题意分析
搜索的策略是:优先找长串,若长串不合法,则回溯,继续找到合法串,直到找到所求合法串的编号,输出即可。
注意的地方就是合法串的判断,根据后缀的规则来判断,枚举后缀长度[1,len/2],后缀中是否有重复子串,若是的话表明不是合法串。
还有一个注意的地方,每次递归调用时,序号就要+1,无论是回溯回来的递归,还是深度搜索的递归,因为没找到一组可行解,编号就要加一。原因是此题不是用递归深度来判断输出的。
代码总览
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <sstream>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <cmath>
#define INF 0x3f3f3f3f
#define nmax 100
#define MEM(x) memset(x,0,sizeof(x))
using namespace std;
int s[nmax];
int ans[nmax],n,a,cot;
bool isfind;
void output(int num)
{
bool isnext = true;
for(int ct = 1;ct<num;++ct){
printf("%c",ans[ct]+'A'-1);
if(ct%4 == 0 && ct % 64 != 0 && ct!=num-1){printf(" "); isnext = false;}
else if( ct % 64 == 0) {printf("\n"); isnext = true;}
else isnext = false;
}
if(!isnext) printf("\n");
printf("%d\n",num-1);
}
void dfs(int num)
{
if(isfind) return;
if(cot == n){
output(num);
isfind = true;
return;
}
for(int i = 1; i<=a;++i){
ans[num] = i;
bool legal = true;
if(num != 1){
//check
// j 后缀长度
for(int j = 1;j<=num/2;++j){
int legal1 = true;// 当前后缀存在重复子串
for(int k = 0;k<j;++k){
if(ans[num-k] != ans[num-j-k]) legal1 = false;
}
if(legal1){
legal = false;
break;
}
}
if(isfind) return;
}
if(legal){
cot++;
dfs(num+1);
}
}
}
int main()
{
//freopen("in.txt","r",stdin);
while(scanf("%d%d",&n,&a) &&(n||a)){
cot = 0;
isfind = false;
MEM(ans);
dfs(1);
}
return 0;
}