http://acm.pku.edu.cn/JudgeOnline/problem?id=1223

Код:
import java.util.*;

public class Main {
	static Tree tree;
	static String[] s;
	static String[] res;
	static char[] cs, ds;
	static int num, size;
	public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
sc.nextLine();
for (int k = 1; k <= t; k++) {
	System.out.printf("DATASET #%d%n", k);
	tree = new Tree("");
	size = 1;
	tree.add();
	s = new String[27];
	cs = sc.nextLine().toCharArray();
	ds = sc.nextLine().toCharArray();
	boolean[] b = new boolean[27];
	num = 0;
	for (char c : cs) {
int id = f(c);
if (!b[id]) num++;
b[id] = true;
	}
	if (search(0, 0, 0) != 1) System.out.println("MULTIPLE TABLES");
	else {
for (int i = 0; i < 27; i++) {
	if (res[i] != null) System.out.println(g(i) + " = " + res[i]);
}
	}
}
	}
	static int f(char c) {
if (c == ' ') return 0;
return c - 'A' + 1;
	}
	static char g(int i) {
if (i == 0) return ' ';
return (char)('A' + i - 1);
	}
	static int search(int p, int q, int r) {
if (p == cs.length) {
	if (q == ds.length && num == size && r++ == 0) res = s.clone();
	return r;
}
if (q >= ds.length) return r;
int id = f(cs[p]);
if (s[id] != null) {
	if (q + s[id].length() > ds.length) return r;
	for (int i = 0; i < s[id].length(); i++) {
if (ds[q + i] != s[id].charAt(i)) return r;
	}
	return search(p + 1, q + s[id].length(), r);
}
Stack<Tree> st = new Stack<Tree>();
Tree t = tree.child[ds[q] - '0'];
for (int i = q; !t.has; i++) {
	if (t.end) {
s[id] = t.s;
t.has = true;
r = search(p + 1, i + 1, r);
if (r > 1) return r;
t.has = false;
s[id] = null;
if (size >= num) break;
st.add(t);
t.add();
	}
	if (i + 1 >= ds.length) break;
	t = t.child[ds[i + 1] - '0'];
}
for (Tree tr : st) {
	tr.remove();
}
return r;
	}
	static class Tree {
String s;
Tree[] child;
boolean end, has;
Tree(String s) {
	this.s = s;
	end = true;
}
void add() {
	size++;
	if (child == null) child = new Tree[]{new Tree(s + "0"), new Tree(s + "1")};
	end = false;
}
void remove() {
	size--;
	end = true;
}
	}
}