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 |
import java.io.IOException;
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Scanner;
import java.util.TreeSet;
class Main
{
public static final boolean DEBUG = false;
public static final int N = 40;
public static char[] buf = new char[N];
public static char[] b = new char[N];
public static TreeSet<Integer> ts = new TreeSet<Integer>();
public static int ans, n;
public static void dfs(int cur)
{
if (cur >= 3) {
int t = cur / 3 * 3;
for (int i = 3; i <= t; i += 3) {
int temp = 0;
for (int j = cur - i; j < cur; j++) {
temp <<= 1;
temp |= b[j] - '0';
}
if (ts.contains(temp)) return;
}
}
if (cur == n) {
ans++;
return;
}
if (buf[cur] != '*') {
b[cur] = buf[cur];
dfs(cur + 1);
} else {
b[cur] = '0';
dfs(cur + 1);
b[cur] = '1';
dfs(cur + 1);
}
}
public static void main(String[] args) throws IOException
{
Scanner cin;
String s;
int t = 1;
if (DEBUG) {
cin = new Scanner(new FileReader("d:\\OJ\\uva_in.txt"));
} else {
cin = new Scanner(new InputStreamReader(System.in));
}
for (int i = 1; i <= 10; i++) {
for (int j = 0; j < (1 << i); j++) {
ts.add(j | (j << i) | (j << (2 * i)));
}
}
while (cin.hasNext()) {
n = cin.nextInt();
if (n == 0) break;
s = cin.next();
buf = s.toCharArray();
ans = 0;
dfs(0);
System.out.println("Case " + (t++) + ": " + ans);
}
}
}