Adding some more judges, here and there.
[and.git] / NEERC / kequiv / kequiv_ia_vd.java
blob57d8d992870787bad2ff5c70f0fed3d42750295a
1 import java.io.*;
2 import java.util.*;
4 /**
5 * @author Iskander Akishev
6 * @author Vladimir Danilov
7 */
8 public class kequiv_ia_vd implements Runnable {
10 private static final String FILE_NAME = "kequiv";
12 public void run() {
13 try {
14 solve();
15 } catch (Throwable t) {
16 t.printStackTrace();
17 System.exit(1);
21 private BufferedReader in;
22 private PrintWriter out;
24 enum Type {
25 FULL, NORMAL
28 private final Node FULL_NODE = new Node(Type.FULL);
30 class Node {
31 Node[] children;
32 Type type;
33 int classId = -1;
35 Node(Type type) {
36 this.type = type;
37 children = new Node[10];
40 @Override
41 public boolean equals(Object o) {
42 return hashCode() == o.hashCode();
45 @Override
46 public int hashCode() {
47 if (classId == -1) {
48 if (type == Type.FULL) {
49 return -12354125;
51 classId = children != null ? Arrays.hashCode(children) : 0;
53 return classId;
56 public int getClassId() {
57 return hashCode();
61 private void solve() throws Exception {
62 in = new BufferedReader(new FileReader(FILE_NAME + ".in"));
63 out = new PrintWriter(new File(FILE_NAME + ".out"));
65 Node root = new Node(Type.NORMAL);
66 int n = Integer.parseInt(in.readLine());
67 for (int i = 0; i < n; i++) {
68 StringTokenizer st = new StringTokenizer(in.readLine());
69 String a = readNumber(st);
70 String b = readNumber(st);
71 insert(root, a, b, 0);
74 int[] col = new int[10];
75 for (int i = 1; i < 10; i++) {
76 col[i] = i;
78 for (int i = 1; i < 10; i++) {
79 for (int j = i + 1; j < 10; j++) {
80 if (check(root, i, j)) {
81 col[j] = col[i] = Math.min(col[j], col[i]);
86 for (int i = 1; i < 10; i++) {
87 if (col[i] == i) {
88 for (int j = 0; j < 10; j++) {
89 if (col[j] == col[i]) {
90 out.print(j);
93 out.println();
97 in.close();
98 out.close();
101 private boolean check(Node r, int a, int b) {
102 if (r == null) {
103 return true;
105 if (r.type == Type.NORMAL) {
106 if (r.children[a] == null || r.children[b] == null) {
107 if (r.children[a] != r.children[b]) {
108 return false;
110 } else if (r.children[a].getClassId() != r.children[b].getClassId()) {
111 return false;
113 for (Node ch : r.children) {
114 if (!check(ch, a, b)) {
115 return false;
119 return true;
122 private Node insert(Node root, String a, String b, int h) {
123 if (root == null) {
124 root = new Node(Type.NORMAL);
127 if (h == M + 1) {
128 return FULL_NODE;
130 if (charsOnly(a, h, '0') && charsOnly(b, h, '9')) {
131 return FULL_NODE;
133 int ca = a.charAt(h) - '0';
134 int cb = b.charAt(h) - '0';
136 if (ca == cb) {
137 root.children[ca] = insert(root.children[ca], a, b, h + 1);
138 } else {
139 root.children[ca] = insert(root.children[ca], a, generate(a, h, '9'), h + 1);
140 for (int i = ca + 1; i < cb; i++) {
141 root.children[i] = FULL_NODE;
143 root.children[cb] = insert(root.children[cb], generate(b, h, '0'), b, h + 1);
146 return root;
149 private String generate(String s, int h, char c) {
150 return s.substring(0, h + 1) + chars[c - '0'][M - (h + 1)];
153 private boolean charsOnly(String s, int h, char c) {
154 for (int i = h; i < M; i++) {
155 if (s.charAt(i) != c)
156 return false;
158 return true;
161 final static int M = 19;
162 final static String[][] chars;
163 static {
164 chars = new String[10][M + 1];
165 for (int i = 0; i < 10; i++) {
166 chars[i][0] = "";
167 for (int j = 1; j < M + 1; j++) {
168 chars[i][j] = chars[i][j - 1] + i;
173 private String readNumber(StringTokenizer st) {
174 String res = st.nextToken();
175 return chars[0][M - res.length()] + res;
178 public static void main(String[] args) {
179 new Thread(new kequiv_ia_vd()).start();