1
+ package codejam2015 .qualification ;
2
+
3
+ import java .io .*;
4
+ import java .util .*;
5
+
6
+ public class Dijkstra {
7
+
8
+ // general part
9
+ private static final String INPUT = "src/main/resources" ;
10
+ private static final String OUTPUT = "target/output" ;
11
+ private static final String ROUND = "codejam2015/qualification" ;
12
+
13
+ private static final String SAMPLE = "C-sample.in" ;
14
+ private static final String SMALL = "C-small-practice.in" ;
15
+ private static final String LARGE = "C-large.in" ;
16
+
17
+ private Scanner scanner ;
18
+ private PrintWriter writer ;
19
+
20
+ public Dijkstra (InputStream is , OutputStream os ) {
21
+ scanner = new Scanner (is );
22
+ writer = new PrintWriter (os );
23
+ }
24
+
25
+ public void close () {
26
+ scanner .close ();
27
+ writer .flush ();
28
+ }
29
+
30
+ private static void runTest (String fileName , boolean isConsole ) throws Exception {
31
+ InputStream is = initInputStream (fileName );
32
+ OutputStream os = initOutputStream (fileName , isConsole );
33
+
34
+ Dijkstra problem = new Dijkstra (is , os );
35
+ problem .solve ();
36
+ problem .close ();
37
+
38
+ doneStreams (isConsole , is , os );
39
+ }
40
+
41
+ private static InputStream initInputStream (String fileName ) throws FileNotFoundException {
42
+ File inputDir = new File (INPUT + File .separator + ROUND );
43
+ File inputFile = new File (inputDir , fileName );
44
+ InputStream is = new FileInputStream (inputFile );
45
+ return is ;
46
+ }
47
+
48
+ private static OutputStream initOutputStream (String fileName , boolean isConsole ) throws FileNotFoundException {
49
+ OutputStream os = System .out ;
50
+ if (isConsole ) {
51
+ System .out .println (fileName );
52
+ System .out .println (" ---] cut [---" );
53
+ } else {
54
+ File outputDir = new File (OUTPUT + File .separator + ROUND );
55
+ outputDir .mkdirs ();
56
+
57
+ File outputFile = new File (outputDir , fileName .replace (".in" , ".out" ));
58
+ os = new PrintStream (new FileOutputStream (outputFile ));
59
+ }
60
+ return os ;
61
+ }
62
+
63
+ private static void doneStreams (boolean isConsole , InputStream is , OutputStream os ) throws IOException {
64
+ is .close ();
65
+ if (isConsole ) {
66
+ System .out .println (" ---] cut [---" );
67
+ System .out .println ("" );
68
+ } else {
69
+ os .close ();
70
+ }
71
+ }
72
+
73
+ public static void main (String [] args ) {
74
+ try {
75
+ runTest (SAMPLE , true );
76
+ runTest (SMALL , false );
77
+ // runTest(LARGE, false);
78
+ } catch (Exception e ) {
79
+ e .printStackTrace ();
80
+ }
81
+ }
82
+
83
+ // problem part
84
+
85
+ /**
86
+ * Solve the problem
87
+ */
88
+ public void solve () {
89
+ // 1 <= T <= 230
90
+ int t = scanner .nextInt ();
91
+ scanner .nextLine ();
92
+
93
+ for (int i = 1 ; i <= t ; i ++) {
94
+ writer .print ("Case #" );
95
+ writer .println (i + ": " );
96
+
97
+ // 1 <= L <= 10000.
98
+ // 1 <= X <= 10^12.
99
+ // 1 <= L * X <= 10^16.
100
+
101
+ int l = scanner .nextInt ();
102
+ long x = scanner .nextLong ();
103
+
104
+ String chars = scanner .next ();
105
+
106
+ writer .printf ("%1s\n " , greedy (l , x , chars ));
107
+ }
108
+ }
109
+
110
+ private String greedy (int l , long x , String string ) {
111
+ StringBuilder sb = new StringBuilder ();
112
+ for (int i =0 ; i <x ; i ++)
113
+ sb .append (string );
114
+
115
+ char [] chars = sb .toString ().toCharArray ();
116
+ // Quaternion[][][] dp = new Quaternion[chars.length][chars.length][3];
117
+
118
+ for (int i =1 ; i <chars .length -1 ; i ++) {
119
+ Quaternion dp1 = calc (chars , 0 , i );
120
+ Quaternion dp2 = Quaternion .one ;
121
+ Quaternion dp3 = calc (chars , i , chars .length );
122
+ for (int j =i +1 ; j <=chars .length - 1 ; j ++) {
123
+ /*
124
+ dp[i-1][j][0] = calc(chars, 0, i);
125
+ dp[i-1][j][1] = calc(chars, i, j);
126
+ dp[i-1][j][2] = calc(chars, j, chars.length);
127
+ */
128
+
129
+ dp2 = dp2 .mult (new Quaternion (chars [j -1 ]));
130
+ dp3 = dp3 .div (new Quaternion (chars [j -1 ]));
131
+
132
+ if (Quaternion .i .equals (dp1 ) &&
133
+ Quaternion .j .equals (dp2 ) &&
134
+ Quaternion .k .equals (dp3 ) ) {
135
+ return "YES" ;
136
+ }
137
+ }
138
+ }
139
+
140
+ return "NO" ;
141
+ }
142
+
143
+ private Quaternion calc (char [] chars , int a , int b ) {
144
+ Quaternion quaternion = new Quaternion (chars [a ]);
145
+ for (int i =a +1 ; i <b ; i ++)
146
+ quaternion = quaternion .mult (new Quaternion (chars [i ]));
147
+ return quaternion ;
148
+ }
149
+
150
+ private enum QChar {
151
+ ONE , I , J , K ;
152
+
153
+ @ Override
154
+ public String toString () {
155
+ if (this .name ().equals ("ONE" ))
156
+ return "1" ;
157
+ return this .name ().toLowerCase ();
158
+ }
159
+ }
160
+
161
+ private static class Quaternion {
162
+ private QChar qChar ;
163
+ private boolean sign ;
164
+
165
+ public static final Quaternion i = new Quaternion (QChar .I );
166
+ public static final Quaternion j = new Quaternion (QChar .J );
167
+ public static final Quaternion k = new Quaternion (QChar .K );
168
+ public static final Quaternion one = new Quaternion (QChar .ONE );
169
+
170
+ private static final Map <QuaternionPair , Quaternion > divMap = new HashMap <QuaternionPair , Quaternion >();
171
+ static {
172
+ for (QChar a : QChar .values ()) {
173
+ for (boolean signA : new boolean []{false , true }) {
174
+ for (QChar b : QChar .values ()) {
175
+ for (boolean signB : new boolean []{false , true }) {
176
+ Quaternion qA = new Quaternion (a , signA );
177
+ Quaternion qB = new Quaternion (b , signB );
178
+ divMap .put (new QuaternionPair (qA .mult (qB ), qA ), qB );
179
+ }
180
+ }
181
+ }
182
+ }
183
+ }
184
+
185
+
186
+ public Quaternion (QChar qChar , boolean sign ) {
187
+ this .qChar = qChar ;
188
+ this .sign = sign ;
189
+ }
190
+
191
+ public Quaternion (QChar qChar ) {
192
+ this (qChar , false );
193
+ }
194
+
195
+ public Quaternion (String ch ) {
196
+ this (QChar .valueOf (ch .toUpperCase ()), false );
197
+ }
198
+
199
+ public Quaternion (char ch ) {
200
+ this (QChar .valueOf (new String (new char [] {Character .toUpperCase (ch )})), false );
201
+ }
202
+
203
+ public static Quaternion neg (Quaternion quaternion ) {
204
+ return new Quaternion (quaternion .qChar , !quaternion .sign );
205
+ }
206
+
207
+ public Quaternion mult (Quaternion quaternion ) {
208
+ Quaternion result = multUnsigned (quaternion );
209
+ result .sign ^= sign ^ quaternion .sign ;
210
+ return result ;
211
+ }
212
+
213
+ public Quaternion div (Quaternion quaternion ) {
214
+ return divMap .get (new QuaternionPair (this , quaternion ));
215
+ }
216
+
217
+ private Quaternion multUnsigned (Quaternion quaternion ) {
218
+ switch (qChar ) {
219
+ case ONE :
220
+ return new Quaternion (quaternion .qChar );
221
+ case I :
222
+ return multUnsignedI (quaternion );
223
+ case J :
224
+ return multUnsignedJ (quaternion );
225
+ case K :
226
+ return multUnsignedK (quaternion );
227
+ }
228
+ throw new IllegalArgumentException ();
229
+ }
230
+
231
+ private Quaternion multUnsignedI (Quaternion quaternion ) {
232
+ switch (quaternion .qChar ) {
233
+ case ONE :
234
+ return new Quaternion (QChar .I );
235
+ case I :
236
+ return new Quaternion (QChar .ONE , true );
237
+ case J :
238
+ return new Quaternion (QChar .K );
239
+ case K :
240
+ return new Quaternion (QChar .J , true );
241
+ }
242
+ throw new IllegalArgumentException ();
243
+ }
244
+
245
+ private Quaternion multUnsignedJ (Quaternion quaternion ) {
246
+ switch (quaternion .qChar ) {
247
+ case ONE :
248
+ return new Quaternion (QChar .J );
249
+ case I :
250
+ return new Quaternion (QChar .K , true );
251
+ case J :
252
+ return new Quaternion (QChar .ONE , true );
253
+ case K :
254
+ return new Quaternion (QChar .I );
255
+ }
256
+ throw new IllegalArgumentException ();
257
+ }
258
+
259
+ private Quaternion multUnsignedK (Quaternion quaternion ) {
260
+ switch (quaternion .qChar ) {
261
+ case ONE :
262
+ return new Quaternion (QChar .K );
263
+ case I :
264
+ return new Quaternion (QChar .J );
265
+ case J :
266
+ return new Quaternion (QChar .I , true );
267
+ case K :
268
+ return new Quaternion (QChar .ONE , true );
269
+ }
270
+ throw new IllegalArgumentException ();
271
+ }
272
+
273
+
274
+ @ Override
275
+ public boolean equals (Object o ) {
276
+ if (this == o ) return true ;
277
+ if (!(o instanceof Quaternion )) return false ;
278
+
279
+ Quaternion that = (Quaternion ) o ;
280
+
281
+ if (sign != that .sign ) return false ;
282
+ return qChar == that .qChar ;
283
+
284
+ }
285
+
286
+ @ Override
287
+ public int hashCode () {
288
+ int result = qChar .hashCode ();
289
+ result = 31 * result + (sign ? 1 : 0 );
290
+ return result ;
291
+ }
292
+
293
+ @ Override
294
+ public String toString () {
295
+ if (sign )
296
+ return "-" + qChar .toString ();
297
+
298
+ return qChar .toString ();
299
+ }
300
+ }
301
+
302
+ private static class QuaternionPair {
303
+ private final Quaternion a ;
304
+ private final Quaternion b ;
305
+
306
+ public QuaternionPair (Quaternion a , Quaternion b ) {
307
+ this .a = a ;
308
+ this .b = b ;
309
+ }
310
+
311
+ @ Override
312
+ public boolean equals (Object o ) {
313
+ if (this == o ) return true ;
314
+ if (!(o instanceof QuaternionPair )) return false ;
315
+
316
+ QuaternionPair that = (QuaternionPair ) o ;
317
+
318
+ if (!a .equals (that .a )) return false ;
319
+ return b .equals (that .b );
320
+
321
+ }
322
+
323
+ @ Override
324
+ public int hashCode () {
325
+ int result = a .hashCode ();
326
+ result = 31 * result + b .hashCode ();
327
+ return result ;
328
+ }
329
+ }
330
+ }
0 commit comments