UVa11127 - Triple-Free Binary Strings

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.Queue;
import java.util.LinkedList;

class Main
{
	public static final boolean DEBUG = false;
	public static final int MaxNodes = 36000;
	public static final int N = 2, M = 40;
	public static int[][] ch = new int[MaxNodes][N];
	public static int[] flag = new int[MaxNodes];
	public static int[] fail = new int[MaxNodes];
	public static int[][] f = new int[M][MaxNodes];
	public static int numOfNodes;
	
	public static void insert(int w, int len)
	{
		int cur = 0;
		for (int i = 0; i < len; i++) {
			int c = (w >> i) & 1;
			if (ch[cur][c] == 0) {
				ch[cur][c] = numOfNodes++;
			}
			cur = ch[cur][c];
		}
		flag[cur] = 1;
	}
	
	public static void getFail()
	{
		Queue<Integer> q = new LinkedList<Integer>();
		q.add(0);
		
		while (!q.isEmpty()) {
			int u = q.poll();
			
			for (int i = 0; i < N; i++) {
				int v = ch[u][i];
				if (v == 0) continue;
				
				if (u == 0) {
					fail[v] = 0;
				} else {
					int f = fail[u];
					while (f != 0 && ch[f][i] == 0) f = fail[f];
					
					fail[v] = ch[f][i];
				}
				
				flag[v] |= flag[u] | flag[fail[v]];
				q.add(v);
			}
		}
	}
	
	public static int next(int u, int c)
	{
		while (u != 0 && ch[u][c] == 0) u = fail[u];
		
		return ch[u][c];
	}
	
	public static void init()
	{
		numOfNodes = 1;
		
		for (int i = 1; i <= 10; i++) {
			for (int j = 0; j < (1 << i); j++) {
				insert(j | (j << i) | (j << (2 * i)), 3 * i);
			}
		}
		
		getFail();
	}
	
	public static void main(String[] args) throws IOException
	{
		Scanner cin;
		int n;
		int cs = 1;
		
		if (DEBUG) {
			cin = new Scanner(new FileReader("d:\\OJ\\uva_in.txt"));
		} else {
			cin = new Scanner(new InputStreamReader(System.in));
		}
		
		init();
		
		while (cin.hasNext()) {
			n = cin.nextInt();
			if (n == 0) break;
			
			String s = cin.next();
			char[] pat = s.toCharArray();
			for (int i = 0; i < numOfNodes; i++) {
				f[n][i] = (flag[i] == 1) ? 0 : 1;
			}
			
			for (int i = n - 1; i >= 0; i--) {
				for (int j = 0; j < numOfNodes; j++) {
					if (flag[j] != 0) continue;
					
					f[i][j] = 0;
					for (int k = 0; k < N; k++) {
						if (pat[i] != '*' && pat[i] != '0' + k) continue;
						f[i][j] += f[i + 1][next(j, k)];
					}
				}
			}
			
			System.out.println("Case " + (cs++) + ": " + f[0][0]);
		}
		
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kgduu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值