UVA-129 Krypton Factor 困难的串

题目链接:https://vjudge.net/problem/UVA-129

题意:如果一个字符串包含两个相邻的重复子串,则称它为“容易的串”,否则称为“困难的串”,例如,BB,ABCDABCD,ABCDACABCAB,都是容易的串,而D,ABAC,都是困难的串。输入正整数n,L,让你找出由字母表前L个大写字母组成的字典序第n小的困难的串,并且输出这个串的长度。输出格式请点击上面题目链接参加原题。例如:L=3时,前7个困难的串为A,AB,ABA,ABAC,ABACA,ABACAB,ABACABA。

分析:分析题意,貌似是一个全排列问题,可是需要我们生成所有由前L个大写字母组成的排列吗?那样计算量太大了。我们知道,全排列个数是一个阶乘级的数字,数字很容易爆炸。仔细想想可知,这道题可以用回溯法解决,可以减少很多没必要的判断。每次往答案后面添加一个字母,在这里,我们只需要判断包含这个字母的串是否合法,即只需要判断当前串的后缀即可。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=105;
int n,L;
int cnt,flag;
char ans[maxn];

void dfs(int cur) {
    if(cnt==n) {// 如果找到了第n个串就输出答案并结束
        flag=0;
        for(int i=0; i<cur; i++) { //输出格式
            if(i%64==0&&i) cout<<endl;
            else if(i%4==0&&i) cout<<' ';
            cout<<ans[i];
        }
        cout<<endl;
        cout<<cur<<endl;
    } else {
        for(int i=0; i<L&&flag; i++) {
            int ok=1;
            ans[cur]=i+'A';//尝试把第个字母放入串中
            for(int j=1; j*2<=cur+1&&ok; j++) {  //判断是否合法
                int is_equal=1;
                for(int k=0; k<j; k++) { 
                    if(ans[cur-k]!=ans[cur-k-j]) { //每个后缀中如果有一个字母不一样就可以判断当前后缀合法
                        is_equal=0;
                        break;
                    }
                }
                if(is_equal) {ok=0;break;}
            }
            if(ok) { //如果合法就继续寻找下一个字母
                cnt++;
                dfs(cur+1);
            }
        }
    }
    return;
}

int main () {
    //freopen("in.txt", "r", stdin);
    while(cin>>n>>L&&(n||L)) {
        cnt=0;
        flag=1;
        dfs(0);
    }
    return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值