結果
問題 | No.5019 Hakai Project |
ユーザー | ks2m |
提出日時 | 2023-11-18 18:02:29 |
言語 | Java21 (openjdk 21) |
結果 |
AC
|
実行時間 | 1,190 ms / 3,000 ms |
コード長 | 11,357 bytes |
コンパイル時間 | 3,131 ms |
コンパイル使用メモリ | 94,164 KB |
実行使用メモリ | 63,020 KB |
スコア | 1,381,565,518 |
最終ジャッジ日時 | 2023-11-18 18:03:25 |
合計ジャッジ時間 | 56,199 ms |
ジャッジサーバーID (参考情報) |
judge14 / judge15 |
純コード判定しない問題か言語 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 867 ms
61,784 KB |
testcase_01 | AC | 1,004 ms
62,668 KB |
testcase_02 | AC | 894 ms
61,824 KB |
testcase_03 | AC | 996 ms
62,932 KB |
testcase_04 | AC | 903 ms
61,840 KB |
testcase_05 | AC | 935 ms
62,604 KB |
testcase_06 | AC | 883 ms
61,764 KB |
testcase_07 | AC | 1,070 ms
61,920 KB |
testcase_08 | AC | 842 ms
62,528 KB |
testcase_09 | AC | 974 ms
61,704 KB |
testcase_10 | AC | 794 ms
61,644 KB |
testcase_11 | AC | 865 ms
61,484 KB |
testcase_12 | AC | 1,058 ms
61,868 KB |
testcase_13 | AC | 941 ms
62,700 KB |
testcase_14 | AC | 940 ms
61,836 KB |
testcase_15 | AC | 850 ms
62,604 KB |
testcase_16 | AC | 861 ms
61,900 KB |
testcase_17 | AC | 921 ms
62,672 KB |
testcase_18 | AC | 821 ms
61,776 KB |
testcase_19 | AC | 903 ms
62,792 KB |
testcase_20 | AC | 917 ms
61,696 KB |
testcase_21 | AC | 1,037 ms
61,788 KB |
testcase_22 | AC | 1,045 ms
62,872 KB |
testcase_23 | AC | 986 ms
62,460 KB |
testcase_24 | AC | 950 ms
62,924 KB |
testcase_25 | AC | 890 ms
61,804 KB |
testcase_26 | AC | 791 ms
61,768 KB |
testcase_27 | AC | 953 ms
61,712 KB |
testcase_28 | AC | 846 ms
61,676 KB |
testcase_29 | AC | 936 ms
62,908 KB |
testcase_30 | AC | 815 ms
61,684 KB |
testcase_31 | AC | 866 ms
61,736 KB |
testcase_32 | AC | 918 ms
61,712 KB |
testcase_33 | AC | 953 ms
62,676 KB |
testcase_34 | AC | 907 ms
61,732 KB |
testcase_35 | AC | 842 ms
61,856 KB |
testcase_36 | AC | 713 ms
61,692 KB |
testcase_37 | AC | 965 ms
61,752 KB |
testcase_38 | AC | 758 ms
61,996 KB |
testcase_39 | AC | 1,037 ms
62,660 KB |
testcase_40 | AC | 885 ms
63,020 KB |
testcase_41 | AC | 827 ms
61,808 KB |
testcase_42 | AC | 929 ms
61,904 KB |
testcase_43 | AC | 911 ms
62,640 KB |
testcase_44 | AC | 787 ms
61,652 KB |
testcase_45 | AC | 776 ms
61,696 KB |
testcase_46 | AC | 978 ms
62,572 KB |
testcase_47 | AC | 760 ms
61,556 KB |
testcase_48 | AC | 1,081 ms
61,916 KB |
testcase_49 | AC | 1,190 ms
62,696 KB |
ソースコード
import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.InputStreamReader; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.PriorityQueue; import java.util.Set; public class Main { static boolean readFile = false; static int caseNum = 0; static long startTime; static int[] dx = {1, 0, -1, 0}; static int[] dy = {0, 1, 0, -1}; static int N, M; static char[][] s; static Bomb[] bbs; public static void main(String[] args) throws Exception { if (readFile) { long score = solve(caseNum); System.out.println(score); } else { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); init(br); solve(br); br.close(); } } static long solve(int z) throws Exception { StringBuilder sb = new StringBuilder(); sb.append(z); while (sb.length() < 4) { sb.insert(0, '0'); } File file = new File("G:\\yuki\\008\\in\\" + sb.toString() + ".txt"); BufferedReader br = new BufferedReader(new FileReader(file)); init(br); long res = solve(br); br.close(); return res; } static void init(BufferedReader br) throws Exception { startTime = System.currentTimeMillis(); String[] sa = br.readLine().split(" "); N = Integer.parseInt(sa[0]); M = Integer.parseInt(sa[1]); s = new char[N][N]; for (int i = 0; i < N; i++) { s[i] = br.readLine().toCharArray(); } bbs = new Bomb[M]; for (int i = 0; i < M; i++) { Bomb o = new Bomb(); sa = br.readLine().split(" "); o.i = i + 1; o.c = Integer.parseInt(sa[0]); o.l = Integer.parseInt(sa[1]); o.a = new int[o.l]; o.b = new int[o.l]; for (int j = 0; j < o.l; j++) { sa = br.readLine().split(" "); o.a[j] = Integer.parseInt(sa[0]); o.b[j] = Integer.parseInt(sa[1]); } // o.v = (double) o.c / o.l; bbs[i] = o; } } static long solve(BufferedReader br) throws Exception { // Arrays.sort(bbs, (o1, o2) -> Double.compare(o1.v, o2.v)); int[][] d = getDist(); int[][] v = new int[N][N]; List<Use> list = new ArrayList<>(); for (int x = 0; x < N; x++) { for (int y = 0; y < N; y++) { if (s[x][y] != '.' && v[x][y] == 0) { double bestCosp = 0; Bomb bb = null; int bx = 0; int by = 0; for (Bomb o : bbs) { int tryCnt = 0; for (int li = o.l - 1; li >= 0 && tryCnt < 300; li--) { int cx = x - o.a[li]; if (cx < 0 || N <= cx) continue; int cy = y - o.b[li]; if (cy < 0 || N <= cy) continue; tryCnt++; int cnt = 0; for (int li2 = 0; li2 < o.l; li2++) { int x2 = cx + o.a[li2]; if (x2 < 0 || N <= x2) continue; int y2 = cy + o.b[li2]; if (y2 < 0 || N <= y2) continue; if (s[x2][y2] != '.' && v[x2][y2] == 0) { cnt++; } } double cosp = (double) cnt / (o.c + d[cx][cy]); if (cosp > bestCosp) { bestCosp = cosp; bb = o; bx = cx; by = cy; } } } for (int li2 = 0; li2 < bb.l; li2++) { int x2 = bx + bb.a[li2]; if (x2 < 0 || N <= x2) continue; int y2 = by + bb.b[li2]; if (y2 < 0 || N <= y2) continue; v[x2][y2]++; } Use u = new Use(); u.b = bb; u.ux = bx; u.uy = by; list.add(u); } } } // System.out.println(list.size()); Map<Integer, List<Use>> map = new HashMap<>(); for (Use u : list) { setShop(u, d); int k = toInt(u.sx, u.sy); List<Use> list2 = map.get(k); if (list2 == null) { list2 = new ArrayList<>(); map.put(k, list2); } list2.add(u); } List<Event> evs = new ArrayList<>(); int cx = 0; int cy = 0; while (!map.isEmpty()) { int bestk = -1; int bestd = 100000000; for (int k : map.keySet()) { int nx = k / N; int ny = k % N; int dist = Math.abs(nx - cx) + Math.abs(ny - cy); if (dist < bestd) { bestd = dist; bestk = k; } } List<Use> list2 = map.get(bestk); for (Use u : list2) { Event e = new Event(); e.t = 2; e.x = u.sx; e.y = u.sy; e.b = u.b; evs.add(e); } for (Use u : list2) { Event e = new Event(); e.t = 3; e.x = u.ux; e.y = u.uy; e.b = u.b; evs.add(e); } cx = list2.get(list2.size() - 1).ux; cy = list2.get(list2.size() - 1).uy; map.remove(bestk); } Set<Integer> shop = new HashSet<>(); for (int x = 0; x < N; x++) { for (int y = 0; y < N; y++) { if (s[x][y] == '@') { shop.add(toInt(x, y)); } } } int size = evs.size(); for (int i = 0; i < size; i++) { Event e = evs.get(i); if (e.t == 3) { for (int j = 0; j < e.b.l; j++) { int x = e.x + e.b.a[j]; if (x < 0 || N <= x) continue; int y = e.y + e.b.b[j]; if (y < 0 || N <= y) continue; shop.remove(toInt(x, y)); } Event pres = null; int prei = -1; for (int j = i - 1; j >= 0; j--) { Event e2 = evs.get(j); if (e2.t == 2) { pres = e2; prei = j; break; } } for (int j = i + 1; j < size; j++) { Event e2 = evs.get(j); if (e2.t == 2) { int based = Math.abs(pres.x - e2.x) + Math.abs(pres.y - e2.y); int p = toInt(e2.x, e2.y); if (!shop.contains(p)) { int bp = -1; int bestd = 100000000; for (int sp : shop) { int sx = sp / N; int sy = sp % N; int sd = Math.abs(sx - e2.x) + Math.abs(sy - e2.y); if (sd < bestd) { bestd = sd; bp = sp; } } if (bestd <= based) { e2.x = bp / N; e2.y = bp % N; } else { evs.remove(j); e2.x = pres.x; e2.y = pres.y; evs.add(prei, e2); i++; } } } } } } List<String> ans = new ArrayList<>(); cx = 0; cy = 0; for (Event e : evs) { if (cx != e.x || cy != e.y) { move(cx, cy, e.x, e.y, ans); cx = e.x; cy = e.y; } ans.add(e.t + " " + e.b.i); } PrintWriter pw = new PrintWriter(System.out); pw.println(ans.size()); for (String str : ans) { pw.println(str); } pw.flush(); // System.out.println((System.currentTimeMillis() - startTime) + "ms"); long score = 0; // score = score(ans); return score; } static void move(int sx, int sy, int tx, int ty, List<String> ans) { int x1 = Math.min(sx, tx); int x2 = Math.max(sx, tx); int y1 = Math.min(sy, ty); int y2 = Math.max(sy, ty); int h = x2 - x1 + 1; int w = y2 - y1 + 1; char[][] s2 = new char[h][w]; for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { s2[i][j] = s[x1 + i][y1 + j]; } } int[][] d = new int[h][w]; int[][] pre = new int[h][w]; PriorityQueue<Node> que = new PriorityQueue<Node>(); for (int i = 0; i < h; i++) { Arrays.fill(d[i], 100000000); Arrays.fill(pre[i], -1); } d[sx - x1][sy - y1] = 0; que.add(new Node(toInt(sx - x1, sy - y1), 0)); int gx = tx - x1; int gy = ty - y1; while (!que.isEmpty()) { Node cur = que.poll(); int cx = cur.v / N; int cy = cur.v % N; if (cx == gx && cy == gy) { break; } for (int i = 0; i < 4; i++) { int nx = cx + dx[i]; int ny = cy + dy[i]; if (nx < 0 || h <= nx || ny < 0 || w <= ny) { continue; } int alt = d[cx][cy]; if (s[nx][ny] == '.') { alt++; } else { alt += 2; } if (alt < d[nx][ny]) { d[nx][ny] = alt; pre[nx][ny] = cur.v; que.add(new Node(toInt(nx, ny), alt)); } } } List<Integer> route = new ArrayList<>(); route.add(toInt(gx, gy)); int cx = gx; int cy = gy; while (pre[cx][cy] != -1) { int v = pre[cx][cy]; cx = v / N; cy = v % N; route.add(toInt(cx, cy)); } for (int i = route.size() - 1; i > 0; i--) { int v1 = route.get(i); int v1x = v1 / N; int v1y = v1 % N; int v2 = route.get(i - 1); int v2x = v2 / N; int v2y = v2 % N; if (v1x == v2x) { if (v1y < v2y) { ans.add("1 R"); } else { ans.add("1 L"); } } else { if (v1x < v2x) { ans.add("1 D"); } else { ans.add("1 U"); } } } } static void setShop(Use u, int[][] d) { int cx = u.ux; int cy = u.uy; while (s[cx][cy] != '@') { int best = 100000000; int bi = -1; for (int i = 0; i < 4; i++) { int nx = cx + dx[i]; int ny = cy + dy[i]; if (nx < 0 || N <= nx || ny < 0 || N <= ny) { continue; } if (d[nx][ny] < best) { best = d[nx][ny]; bi = i; } } cx = cx + dx[bi]; cy = cy + dy[bi]; } u.sx = cx; u.sy = cy; } static int[][] getDist() { int[][] d = new int[N][N]; PriorityQueue<Node> que = new PriorityQueue<Node>(); for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { if (s[i][j] == '@') { que.add(new Node(toInt(i, j), 0)); } else { d[i][j] = 100000000; } } } int sd = 16; // TODO int sd2 = sd * 2; while (!que.isEmpty()) { Node cur = que.poll(); int cx = cur.v / N; int cy = cur.v % N; for (int i = 0; i < 4; i++) { int nx = cx + dx[i]; int ny = cy + dy[i]; if (nx < 0 || N <= nx || ny < 0 || N <= ny) { continue; } int alt = d[cx][cy]; if (s[nx][ny] == '.') { alt += sd; } else { alt += sd2; } if (alt < d[nx][ny]) { d[nx][ny] = alt; que.add(new Node(toInt(nx, ny), alt)); } } } return d; } static class Node implements Comparable<Node> { int v, d; public Node(int v, int d) { this.v = v; this.d = d; } public int compareTo(Node o) { return d - o.d; } } static class Bomb { int i, c, l; int[] a, b; // double v; } static class Use { Bomb b; int ux, uy, sx, sy; } static class Event { int t, x, y; Bomb b; } static int toInt(int x, int y) { return x * N + y; } static long score(List<String> ans) { long c = 0; int cx = 0; int cy = 0; int b1 = 1; int[] bs = new int[M]; for (int z = 0; z < ans.size(); z++) { String str = ans.get(z); String[] sa = str.split(" "); int t = Integer.parseInt(sa[0]); if (t == 1) { if (sa[1].equals("U")) cx--; if (sa[1].equals("D")) cx++; if (sa[1].equals("L")) cy--; if (sa[1].equals("R")) cy++; if (cx < 0 || N <= cx || cy < 0 || N <= cy) { throw new RuntimeException(cx + "," + cy); } if (s[cx][cy] == '.') { c += b1 * b1; } else { c += b1 * b1 * 2; } } else { int mi = Integer.parseInt(sa[1]) - 1; Bomb bb = bbs[mi]; if (t == 2) { if (s[cx][cy] != '@') { throw new RuntimeException(cx + "," + cy); } bs[mi]++; b1++; c += bb.c; } else { if (bs[mi] <= 0) { throw new RuntimeException(mi + " " + bs[mi]); } bs[mi]--; b1--; for (int i = 0; i < bb.l; i++) { int x = cx + bb.a[i]; if (x < 0 || N <= x) continue; int y = cy + bb.b[i]; if (y < 0 || N <= y) continue; s[x][y] = '.'; } } } } for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { if (s[i][j] != '.') { for (int x = 0; x < N; x++) { System.out.println(s[x]); } throw new RuntimeException(); } } } long ret = Math.max(10, 1000000000000L / (10000 + c)); return ret; } }