uva 11127 - Triple-Free Binary Strings

本文介绍了一个关于计算给定模式下不含三重重复子串的二进制字符串数量的问题。通过递归深度优先搜索结合剪枝策略实现高效求解,并提供了完整的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Problem J
Triple-Free Binary Strings 
Input: 
Standard Input

Output: Standard Output

 

A binary string consists of ones and zeros. Given a binary string T, if  there is no binary string S such that SSS (concatenate three copies of S together) is a substring of T, we say T is triple-free.
 
A pattern consists of ones, zeros and asterisks, where an asterisk(*) can be replaced by either one or zero. For example, the pattern 0**1 contains strings 0001, 0011, 0101, 0111, but not 1001 or 0000.
 
Given a pattern P, how many triple-free binary strings does it contain?
 
Input
Each line of the input represents a test case, which contains the length of pattern, n(0<n<31), and the pattern P. There can be maximum 35 test cases. 
 
The input terminates when n=0.
 
Output
For each test case, print the case number and the answer, shown below. 

 

Sample Input                       Output for Sample Input

4 0**1
5 *****
10 **01**01**
0
 
Case 1: 2
Case 2: 16
Case 3: 9
 

Problemsetter: Rujia Liu
Special Thanks: Shahriar Manzoor

 枚举出所有的字符串,再判断肯定要超时。所以需要剪枝,就是末尾每多考虑一个字符,就判断因这个字符是否会引起不合法,不合法则剪枝。

#include <cstdio>
#include <algorithm>
#include <vector>
#include <map>
#include <queue>
#include <iostream>
#include <stack>
#include <set>
#include <cstring>
#include <stdlib.h>
#include <cmath>
using namespace std;
typedef long long LL;
typedef pair<int, int> P;
const int maxn = 100+5;
const int INF = 1000000000;

char s[maxn];
int n;

bool judge(int d){
    for(int i = 1;i*3 <= (d+1);i++){
        int tag = 1;
        for(int j = d;j >= d-i+1;j--){
            if(s[j] != s[j-i] || s[j] != s[j-2*i]){
                tag = 0;
                break;
            }
        }
        if(tag == 1) return false;
    }
    return true;
}

int dfs(int d){
    if(d == n){
        return 1;
    }
    int ret = 0;
    if(s[d] == '*'){
        s[d] = '0';
        if(judge(d))
            ret += dfs(d+1);
        s[d] = '1';
        if(judge(d))
            ret += dfs(d+1);
        s[d] = '*';
    }
    else{
        if(judge(d))
            ret += dfs(d+1);
    }
    return ret;
}

int main(){
    int kase = 0;
    while(scanf("%d", &n)){
        kase++;
        if(n == 0) break;
        scanf("%s", s);
        printf("Case %d: %d\n", kase, dfs(0));
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值