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