結果

問題 No.5019 Hakai Project
ユーザー ks2mks2m
提出日時 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
権限があれば一括ダウンロードができます

ソースコード

diff #

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;
	}
}
0