結果
問題 | No.5015 Escape from Labyrinth |
ユーザー | Yu_212 |
提出日時 | 2023-04-16 14:03:18 |
言語 | Java21 (openjdk 21) |
結果 |
WA
|
実行時間 | - |
コード長 | 17,610 bytes |
コンパイル時間 | 6,707 ms |
コンパイル使用メモリ | 94,892 KB |
実行使用メモリ | 71,292 KB |
スコア | 41,530 |
最終ジャッジ日時 | 2023-04-16 14:04:38 |
合計ジャッジ時間 | 75,550 ms |
ジャッジサーバーID (参考情報) |
judge15 / judge12 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 607 ms
68,548 KB |
testcase_01 | AC | 656 ms
70,424 KB |
testcase_02 | AC | 601 ms
67,852 KB |
testcase_03 | AC | 620 ms
68,640 KB |
testcase_04 | AC | 655 ms
67,048 KB |
testcase_05 | AC | 642 ms
68,368 KB |
testcase_06 | AC | 596 ms
68,992 KB |
testcase_07 | AC | 608 ms
67,520 KB |
testcase_08 | AC | 576 ms
64,900 KB |
testcase_09 | AC | 587 ms
68,628 KB |
testcase_10 | AC | 597 ms
66,712 KB |
testcase_11 | AC | 594 ms
68,796 KB |
testcase_12 | AC | 637 ms
67,408 KB |
testcase_13 | AC | 590 ms
68,480 KB |
testcase_14 | AC | 631 ms
68,720 KB |
testcase_15 | AC | 591 ms
68,628 KB |
testcase_16 | AC | 613 ms
68,652 KB |
testcase_17 | AC | 626 ms
69,128 KB |
testcase_18 | AC | 580 ms
66,896 KB |
testcase_19 | AC | 580 ms
68,760 KB |
testcase_20 | AC | 636 ms
66,924 KB |
testcase_21 | AC | 607 ms
68,404 KB |
testcase_22 | AC | 610 ms
68,224 KB |
testcase_23 | AC | 593 ms
69,224 KB |
testcase_24 | AC | 610 ms
69,076 KB |
testcase_25 | AC | 591 ms
69,068 KB |
testcase_26 | AC | 587 ms
68,988 KB |
testcase_27 | AC | 626 ms
68,500 KB |
testcase_28 | AC | 584 ms
67,308 KB |
testcase_29 | AC | 585 ms
67,016 KB |
testcase_30 | AC | 573 ms
64,448 KB |
testcase_31 | AC | 693 ms
68,672 KB |
testcase_32 | AC | 622 ms
68,580 KB |
testcase_33 | AC | 606 ms
68,868 KB |
testcase_34 | AC | 691 ms
68,596 KB |
testcase_35 | AC | 685 ms
69,132 KB |
testcase_36 | AC | 617 ms
66,860 KB |
testcase_37 | AC | 609 ms
68,676 KB |
testcase_38 | AC | 603 ms
68,496 KB |
testcase_39 | AC | 619 ms
68,292 KB |
testcase_40 | AC | 572 ms
66,528 KB |
testcase_41 | AC | 595 ms
68,360 KB |
testcase_42 | AC | 583 ms
66,460 KB |
testcase_43 | AC | 594 ms
64,888 KB |
testcase_44 | AC | 704 ms
68,960 KB |
testcase_45 | AC | 605 ms
68,884 KB |
testcase_46 | AC | 617 ms
65,624 KB |
testcase_47 | AC | 571 ms
67,024 KB |
testcase_48 | AC | 713 ms
69,668 KB |
testcase_49 | AC | 660 ms
68,980 KB |
testcase_50 | AC | 680 ms
68,716 KB |
testcase_51 | AC | 619 ms
68,612 KB |
testcase_52 | AC | 675 ms
69,260 KB |
testcase_53 | AC | 647 ms
68,956 KB |
testcase_54 | AC | 649 ms
68,904 KB |
testcase_55 | AC | 656 ms
68,644 KB |
testcase_56 | AC | 670 ms
68,652 KB |
testcase_57 | AC | 645 ms
68,904 KB |
testcase_58 | AC | 590 ms
68,912 KB |
testcase_59 | AC | 629 ms
69,436 KB |
testcase_60 | AC | 640 ms
67,428 KB |
testcase_61 | AC | 569 ms
67,104 KB |
testcase_62 | AC | 625 ms
67,444 KB |
testcase_63 | AC | 668 ms
68,672 KB |
testcase_64 | AC | 626 ms
69,180 KB |
testcase_65 | AC | 598 ms
67,388 KB |
testcase_66 | AC | 680 ms
69,280 KB |
testcase_67 | AC | 574 ms
62,504 KB |
testcase_68 | AC | 587 ms
67,368 KB |
testcase_69 | AC | 642 ms
64,792 KB |
testcase_70 | AC | 593 ms
66,804 KB |
testcase_71 | AC | 616 ms
67,152 KB |
testcase_72 | AC | 637 ms
69,072 KB |
testcase_73 | AC | 574 ms
66,468 KB |
testcase_74 | AC | 621 ms
69,060 KB |
testcase_75 | AC | 698 ms
69,016 KB |
testcase_76 | AC | 660 ms
69,172 KB |
testcase_77 | AC | 593 ms
66,496 KB |
testcase_78 | AC | 624 ms
68,904 KB |
testcase_79 | AC | 583 ms
67,276 KB |
testcase_80 | AC | 622 ms
68,568 KB |
testcase_81 | AC | 625 ms
69,516 KB |
testcase_82 | AC | 600 ms
66,536 KB |
testcase_83 | AC | 573 ms
69,080 KB |
testcase_84 | AC | 623 ms
67,444 KB |
testcase_85 | AC | 646 ms
69,016 KB |
testcase_86 | AC | 577 ms
66,548 KB |
testcase_87 | AC | 626 ms
67,068 KB |
testcase_88 | AC | 577 ms
64,900 KB |
testcase_89 | AC | 603 ms
69,052 KB |
testcase_90 | AC | 595 ms
68,216 KB |
testcase_91 | AC | 604 ms
68,232 KB |
testcase_92 | WA | - |
testcase_93 | AC | 635 ms
67,372 KB |
testcase_94 | AC | 653 ms
66,748 KB |
testcase_95 | AC | 635 ms
68,752 KB |
testcase_96 | AC | 625 ms
68,720 KB |
testcase_97 | AC | 664 ms
67,252 KB |
testcase_98 | AC | 669 ms
68,780 KB |
testcase_99 | AC | 648 ms
69,016 KB |
ソースコード
import java.io.*; import java.util.*; import java.util.concurrent.ThreadLocalRandom; import java.util.function.IntUnaryOperator; import java.util.function.LongUnaryOperator; import java.util.stream.Collectors; public class Main { static boolean isLocal; Random rand = new Random(); In in = new In(System.in); PrintStream out = System.out; long inf = 0x1fffffffffffffffL; int iinf = 0x3fffffff; long startTime; public static final int N = 60; public int D; public static final int H = 1500; public int M; public int J; public char[] grid; public Pos[] ps; public int[] ds; public Pos[] jps; int[] distances; int[][] route; boolean[][] beam = new boolean[60][N * N]; int[] avgWait = new int[N * N]; int[] jid = new int[N * N]; public static final String[] ss = {"M L", "M U", "M R", "M D", "S"}; long solve(int seed) { startTime = System.currentTimeMillis(); in(); distances = new int[(J+3) * (J+3)]; route = new int[(J+3) * (J+3)][]; Arrays.fill(distances, iinf); for (int i = 0; i < M; i++) { for (int d = 0; d < 4; d++) { Pos cur = ps[i]; while (true) { cur = cur.moved((d+2)%4); if (cur == null || grid[cur.z] == '#') { break; } for (int j = 0; j < 60; j += ds[i]) { beam[j][cur.z] = true; } } } } for (int i = 0; i < N * N; i++) { int c = 1; for (int j = 0; j < 60; j++) { if (beam[j][i]) { c++; } else { c = 1; } avgWait[i] += c; } } for (int i = 0; i < J + 3; i++) { calcDist(i); } int tt = 0; int cur = J; BitSet visited = new BitSet(J + 3); visited.set(J + 2); tt = moveTo(J, J+1, tt, visited); visited.clear(J + 2); tt = moveTo(J+1, J+2, tt, visited); debug(totalCost); return 0; } int totalCost = 0; int moveTo(int s, int g, int tt, BitSet visited) { int cur = s; visited.set(s); while (cur != g) { int md = iinf; int mi = -1; for (int i = 0; i < J + 3; i++) { if (visited.get(i)) { continue; } // debug(i, cur, jps[i].dist(jps[g]), distances[cur * (J + 3) + i]); int d = distances[cur * (J + 3) + i] + jps[i].dist(jps[g]) * 50; if (md > d) { md = d; mi = i; } } visited.set(mi); // debug(cur, mi, md, distances[cur * (J + 3) + mi], jps[mi].dist(jps[g]), g); Pos p = jps[cur]; for (int v : route(jps[cur], jps[mi], tt)) { if (v < 4) p = p.moved(v); tt = (tt + 1) % 60; if (beam[tt][p.z]) { totalCost += D; } totalCost++; out.println(ss[v]); } cur = mi; } return tt; } List<Integer> route(Pos s, Pos g, int tt) { class S { private final Pos p; private final int t; private final int d; public S(Pos p, int t, int d) { this.p = p; this.t = t; this.d = d; } } PriorityQueue<S> queue = new PriorityQueue<>(Comparator.comparingInt(v -> v.d)); queue.add(new S(s, tt, 0)); int[][] dist = new int[60][N * N]; int[][] prev = new int[60][N * N]; for (int i = 0; i < 60; i++) { Arrays.fill(dist[i], iinf); Arrays.fill(prev[i], -1); } dist[tt][s.z] = 0; while (!queue.isEmpty()) { S v = queue.remove(); if (dist[v.t][v.p.z] < v.d) { continue; } if (v.p.z == g.z) { List<Integer> route = new ArrayList<>(); Pos cur = v.p; int ct = v.t; while (prev[ct][cur.z] != -1) { route.add(prev[ct][cur.z]); if (prev[ct][cur.z] < 4) { cur = cur.moved((prev[ct][cur.z] + 2) % 4); } ct = (ct + 59) % 60; } Collections.reverse(route); return route; } int nt = (v.t + 1) % 60; for (int d = 0; d < 4; d++) { Pos q = v.p.moved(d); if (q == null || grid[q.z] == '#') { continue; } int cost = dist[v.t][v.p.z] + 1 + (beam[nt][q.z] ? D : 0); if (dist[nt][q.z] > cost) { dist[nt][q.z] = cost; prev[nt][q.z] = d; queue.add(new S(q, nt, cost)); } } int cost = dist[v.t][v.p.z] + 1 + (beam[nt][v.p.z] ? D : 0); if (dist[nt][v.p.z] > cost) { dist[nt][v.p.z] = cost; prev[nt][v.p.z] = 4; queue.add(new S(v.p, nt, cost)); } } throw new RuntimeException(); } // void calcDist(int s, int t) { // Deque<Timing> deque = new ArrayDeque<>(); // deque.add(new Timing(ps[s], t)); // int[] dist = new int[N * N]; // int[] prev = new int[N * N]; // Timing[] prevState = new Timing[N * N]; // Arrays.fill(dist, iinf); // dist[ps[s].z] = 0; // distances[t][s * (M+3) + s] = 0; // route[t][s * (M+3) + s] = new int[0]; // while (!deque.isEmpty()) { // Timing p = deque.removeFirst(); // if (mid[p.p.z] != -1 && mid[p.p.z] != s) { // distances[t][s * (M+3) + mid[p.p.z]] = dist[p.p.z]; // route[t][s * (M+3) + mid[p.p.z]] = new int[dist[p.p.z]]; // int j = dist[p.p.z]; // Timing cur = p; // while (j > 0) { // j--; // route[t][s * (M+3) + mid[p.p.z]][j] = prev[cur.p.z]; // cur = prevState[cur.p.z]; // } // } // int nt = (p.t + 1) % 60; // for (int d = 0; d < 4; d++) { // Pos q = p.p.moved(d); // if (q == null || grid[q.z] == '#' || grid[q.z] == 'E') { // continue; // } // if (beam[q.z][nt]) { // continue; // } // int cost = beam[nt][q.z] ? D : 1; // if (dist[q.z] > dist[p.p.z] + 1 && q.dist(ps[s]) < iinf) { // dist[q.z] = dist[p.p.z] + 1; // prev[q.z] = d; // prevState[q.z] = p; // deque.addLast(new Timing(q, nt)); // } // } // if (dist[p.p.z] > dist[p.p.z] + 1) { // dist[p.p.z] = dist[p.p.z] + 1; // prev[p.p.z] = 5; // prevState[p.p.z] = p; // deque.addLast(new Timing(p.p, nt)); // } // } // } void calcDist(int s) { class S { private final Pos p; private final int d; public S(Pos p, int d) { this.p = p; this.d = d; } } PriorityQueue<S> queue = new PriorityQueue<>(Comparator.comparingInt(v -> v.d)); queue.add(new S(jps[s], 0)); int[] dist = new int[N * N]; Arrays.fill(dist, iinf); dist[jps[s].z] = 0; while (!queue.isEmpty()) { S v = queue.remove(); if (dist[v.p.z] < v.d) { continue; } if (jid[v.p.z] != -1) { distances[s * (J+3) + jid[v.p.z]] = v.d; } for (int d = 0; d < 4; d++) { Pos q = v.p.moved(d); if (q == null || grid[q.z] == '#') { continue; } int cost = dist[v.p.z] + avgWait[q.z]; if (dist[q.z] > cost && q.dist(jps[s]) < iinf) { dist[q.z] = cost; queue.add(new S(q, cost)); } } } } void in() { in.nextInt(); D = in.nextInt(); in.nextInt(); grid = new char[N * N]; int jc = 0; for (int i = 0; i < N; i++) { char[] s = in.nextCharArray(); for (int j = 0; j < N; j++) { grid[i * N + j] = s[j]; if (grid[i * N + j] == 'J') { jc++; } } } M = in.nextInt(); J = jc; jps = new Pos[J + 3]; ps = new Pos[M]; ds = new int[M]; for (int i = 0; i < M; i++) { int y = in.nextInt(); int x = in.nextInt(); int d = in.nextInt(); ps[i] = pos(x, y); ds[i] = d; } jc = 0; Arrays.fill(jid, -1); for (int i = 0; i < N * N; i++) { if (grid[i] == 'S') { jps[J] = pos(i); jid[i] = J; grid[i] = '.'; } else if (grid[i] == 'K') { jps[J + 1] = pos(i); jid[i] = J + 1; grid[i] = '.'; } else if (grid[i] == 'G') { jps[J + 2] = pos(i); jid[i] = J + 2; grid[i] = '.'; } else if (grid[i] == 'J') { jid[i] = jc; jps[jc++] = pos(i); } else if (grid[i] == 'E') { grid[i] = '#'; } } } static Pos pos(int x, int y) { return Pos.instances[y * N + x]; } static Pos pos(int z) { return Pos.instances[z]; } static class Timing { Pos p; int t, z; public Timing(Pos p, int t) { this.p = p; this.t = t; this.z = p.z * 60 + t; } } static class Pos implements Comparable<Pos> { static Pos[] instances; static Pos[] moved; static { instances = new Pos[N * N]; moved = new Pos[4 * N * N]; for (int i = 0; i < N * N; i++) { instances[i] = new Pos(i % N, i / N, i); } for (int i = 0; i < N * N; i++) { for (int d = 0; d < 4; d++) { // LURD int nx = i % N + (d - 1) % 2; int ny = i / N + (d - 2) % 2; if (0 <= nx && nx < N && 0 <= ny && ny < N) { moved[i * 4 + d] = instances[ny * N + nx]; } } } } final int x, y, z; private Pos(int x, int y, int z) { this.x = x; this.y = y; this.z = z; } Pos moved(int d) { return moved[z * 4 + d]; } int dist(Pos o) { return Math.abs(x - o.x) + Math.abs(y - o.y); } Pos[] neighbors() { Pos[] p = new Pos[4]; int i = 0; if ((p[i] = moved(0)) != null) i++; if ((p[i] = moved(1)) != null) i++; if ((p[i] = moved(2)) != null) i++; if ((p[i] = moved(3)) != null) i++; return i == 4 ? p : Arrays.copyOf(p, i); } @Override public int compareTo(Pos o) { return Integer.compare(z, o.z); } @Override public boolean equals(Object o) { return o instanceof Pos && z == ((Pos)o).z; } @Override public int hashCode() { return z; } @Override public String toString() { return String.format("(%d, %d)", x, y); } } static void debug(Object... args) { if (!isLocal) { return; } if (args == null || args.getClass() != Object[].class) { args = new Object[] {args}; } System.err.println(Arrays.stream(args).map(obj -> { Class<?> clazz = obj == null ? null : obj.getClass(); return clazz == byte[].class ? Arrays.toString((byte[])obj) : clazz == short[].class ? Arrays.toString((short[])obj) : clazz == int[].class ? Arrays.toString((int[])obj) : clazz == long[].class ? Arrays.toString((long[])obj) : clazz == char[].class ? Arrays.toString((char[])obj) : clazz == float[].class ? Arrays.toString((float[])obj) : clazz == double[].class ? Arrays.toString((double[])obj) : clazz == boolean[].class ? Arrays.toString((boolean[])obj) : obj instanceof Object[] ? Arrays.deepToString((Object[])obj) : String.valueOf(obj); }).collect(Collectors.joining(" "))); } long elapsed() { return (long)((System.currentTimeMillis() - startTime) * (isLocal ? 1.7 : 1)); } boolean elapsed(long timeLimit) { return elapsed() >= timeLimit; } public static void main(String[] args) { new Main().solve(0); } static class Random { private long x, y, z, w; Random() { this(ThreadLocalRandom.current().nextLong()); } Random(long seed) { this.x = seed; for (int i = 0; i < 20; i++) { rand(); } } private long rand() { long t = x ^ (x << 11); x = y; y = z; z = w; w = w ^ (w >>> 19) ^ t ^ (t >>> 8); return x & 0x7fffffff; } long next() { return rand() << 31 | rand(); } int next(int n) { return (int)(rand() % n); } int next(int l, int r) { return (int)(rand() % (r - l) + l); } double nextDouble() { return rand() / 2147483647.0; } } static class In { private final BufferedReader reader; private StringTokenizer tokenizer; In(InputStream input) { this.reader = new BufferedReader(new InputStreamReader(input), 0x10000); } String next() { try { while (tokenizer == null || !tokenizer.hasMoreTokens()) { tokenizer = new StringTokenizer(reader.readLine()); } } catch (IOException ignored) { } return tokenizer.nextToken(); } int nextInt() { return Integer.parseInt(next()); } long nextLong() { return Long.parseLong(next()); } double nextDouble() { return Double.parseDouble(next()); } char[] nextCharArray() { return next().toCharArray(); } String[] nextStringArray(int n) { String[] s = new String[n]; for (int i = 0; i < n; i++) { s[i] = next(); } return s; } char[][] nextCharGrid(int n, int m) { char[][] a = new char[n][m]; for (int i = 0; i < n; i++) { a[i] = next().toCharArray(); } return a; } int[] nextIntArray(int n) { int[] a = new int[n]; for (int i = 0; i < n; i++) { a[i] = nextInt(); } return a; } int[] nextIntArray(int n, IntUnaryOperator op) { int[] a = new int[n]; for (int i = 0; i < n; i++) { a[i] = op.applyAsInt(nextInt()); } return a; } int[][] nextIntMatrix(int h, int w) { int[][] a = new int[h][w]; for (int i = 0; i < h; i++) { a[i] = nextIntArray(w); } return a; } long[] nextLongArray(int n) { long[] a = new long[n]; for (int i = 0; i < n; i++) { a[i] = nextLong(); } return a; } long[] nextLongArray(int n, LongUnaryOperator op) { long[] a = new long[n]; for (int i = 0; i < n; i++) { a[i] = op.applyAsLong(nextLong()); } return a; } long[][] nextLongMatrix(int h, int w) { long[][] a = new long[h][w]; for (int i = 0; i < h; i++) { a[i] = nextLongArray(w); } return a; } List<List<Integer>> nextEdges(int n, int m, boolean directed) { List<List<Integer>> res = new ArrayList<>(); for (int i = 0; i < n; i++) { res.add(new ArrayList<>()); } for (int i = 0; i < m; i++) { int u = nextInt() - 1; int v = nextInt() - 1; res.get(u).add(v); if (!directed) { res.get(v).add(u); } } return res; } } }