5 * @author Iskander Akishev
6 * @author Vladimir Danilov
8 public class kequiv_ia_vd_memlimit
implements Runnable
{
10 private static final String FILE_NAME
= "kequiv";
15 } catch (Throwable t
) {
21 private BufferedReader in
;
22 private PrintWriter out
;
28 final Map
<NodeInfo
, Integer
> map
= new HashMap
<NodeInfo
, Integer
>();
29 final NodeInfo EMPTY_INFO
= new NodeInfo(null);
30 final NodeInfo FULL_INFO
= new NodeInfo(null);
31 int EMPTY_CLASS_ID
= getClassId(EMPTY_INFO
);
32 int FULL_CLASS_ID
= getClassId(FULL_INFO
);
34 int getClassId(NodeInfo ni
) {
35 Integer res
= map
.get(ni
);
37 map
.put(ni
, res
= map
.size());
45 NodeInfo(int[] classes
) {
46 this.classes
= classes
;
50 public boolean equals(Object o
) {
51 NodeInfo nodeInfo
= (NodeInfo
)o
;
52 if (this == EMPTY_INFO
|| this == FULL_INFO
) {
55 if (o
== EMPTY_INFO
|| o
== FULL_INFO
) {
58 if (!Arrays
.equals(classes
, nodeInfo
.classes
)) return false;
63 public int hashCode() {
64 return classes
!= null ? Arrays
.hashCode(classes
) : 0;
77 public int getClassId() {
79 if (type
== Type
.EMPTY
) {
80 return EMPTY_CLASS_ID
;
81 } else if (type
== Type
.FULL
) {
84 int[] c
= new int[10];
85 for (int i
= 0; i
< 10; i
++) {
86 c
[i
] = children
[i
].getClassId();
88 classId
= kequiv_ia_vd_memlimit
.this.getClassId(new NodeInfo(c
));
94 private void solve() throws Exception
{
95 in
= new BufferedReader(new FileReader(FILE_NAME
+ ".in"));
96 out
= new PrintWriter(new File(FILE_NAME
+ ".out"));
98 Node root
= new Node(Type
.EMPTY
);
99 int n
= Integer
.parseInt(in
.readLine());
100 for (int i
= 0; i
< n
; i
++) {
101 StringTokenizer st
= new StringTokenizer(in
.readLine());
102 String a
= readNumber(st
);
103 String b
= readNumber(st
);
104 insert(root
, a
, b
, 0);
107 int[] col
= new int[10];
108 for (int i
= 1; i
< 10; i
++) {
111 for (int i
= 1; i
< 10; i
++) {
112 for (int j
= i
+ 1; j
< 10; j
++) {
113 if (check(root
, i
, j
)) {
114 col
[j
] = col
[i
] = Math
.min(col
[j
], col
[i
]);
119 for (int i
= 1; i
< 10; i
++) {
121 for (int j
= 0; j
< 10; j
++) {
122 if (col
[j
] == col
[i
]) {
134 private boolean check(Node r
, int a
, int b
) {
135 if (r
.type
== Type
.NORMAL
) {
136 if (r
.children
[a
].getClassId() != r
.children
[b
].getClassId()) {
139 for (Node ch
: r
.children
) {
140 if (!check(ch
, a
, b
)) {
148 private void insert(Node root
, String a
, String b
, int h
) {
150 root
.type
= Type
.FULL
;
151 root
.children
= null;
154 if (charsOnly(a
, h
, '0') && charsOnly(b
, h
, '9')) {
155 root
.type
= Type
.FULL
;
156 root
.children
= null;
159 int ca
= a
.charAt(h
) - '0';
160 int cb
= b
.charAt(h
) - '0';
162 if (root
.type
== Type
.EMPTY
) {
163 root
.type
= Type
.NORMAL
;
164 root
.children
= new Node
[10];
165 for (int i
= 0; i
< 10; i
++) {
166 root
.children
[i
] = new Node(Type
.EMPTY
);
170 insert(root
.children
[ca
], a
, b
, h
+ 1);
172 insert(root
.children
[ca
], a
, generate(a
, h
, '9'), h
+ 1);
173 for (int i
= ca
+ 1; i
< cb
; i
++) {
174 root
.children
[i
] = new Node(Type
.FULL
);
176 insert(root
.children
[cb
], generate(b
, h
, '0'), b
, h
+ 1);
180 private String
generate(String s
, int h
, char c
) {
181 return s
.substring(0, h
+ 1) + chars
[c
- '0'][M
- (h
+ 1)];
184 private boolean charsOnly(String s
, int h
, char c
) {
185 for (int i
= h
; i
< M
; i
++) {
186 if (s
.charAt(i
) != c
)
192 final static int M
= 19;
193 final static String
[][] chars
;
195 chars
= new String
[10][M
+ 1];
196 for (int i
= 0; i
< 10; i
++) {
198 for (int j
= 1; j
< M
+ 1; j
++) {
199 chars
[i
][j
] = chars
[i
][j
- 1] + i
;
204 private String
readNumber(StringTokenizer st
) {
205 String res
= st
.nextToken();
206 return chars
[0][M
- res
.length()] + res
;
209 public static void main(String
[] args
) {
210 new Thread(new kequiv_ia_vd_memlimit()).start();