UVA.129 Krypton Factor (搜索+暴力)

来源:互联网 发布:维斯布鲁克弹跳数据 编辑:程序博客网 时间:2024/05/22 13:11

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;}
1 0