미생물격리


Software Expert Academy [2382] 미생물격리

문제보기
Alt text

소스코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.StringTokenizer;

public class Solution {
	static class Micro implements Comparable<Micro> {
		int r;
		int c;
		long cnt;
		int dir;
		int num;

		public Micro(int r, int c, long cnt, int dir, int num) {
			this.r = r;
			this.c = c;
			this.cnt = cnt;
			this.dir = dir;
			this.num = num;
		}

		@Override
		public int compareTo(Micro o) {
			if (this.cnt > o.cnt) {
				return 1;
			} else if (this.cnt < o.cnt) {
				return -1;
			} else
				return 0;
		}
	}

	static int N, M, K;
	static long ans;
	static List<Micro>[][] micro;
	static Micro[] memo;
	static int[] dx = { -1, 1, 0, 0 };
	static int[] dy = { 0, 0, -1, 1 };

	public static void main(String[] args) throws NumberFormatException, IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int T = Integer.parseInt(br.readLine());

		for (int tc = 1; tc <= T; tc++) {
			StringTokenizer st = new StringTokenizer(br.readLine());
			N = Integer.parseInt(st.nextToken());
			M = Integer.parseInt(st.nextToken());
			K = Integer.parseInt(st.nextToken());
			micro = new ArrayList[N][N];
			memo = new Micro[K];
			ans = 0;

			for (int i = 0; i < N; i++) {
				for (int j = 0; j < N; j++) {
					micro[i][j] = new ArrayList<>();
				}
			}

			for (int i = 0; i < K; i++) {
				st = new StringTokenizer(br.readLine());
				int r = Integer.parseInt(st.nextToken());
				int c = Integer.parseInt(st.nextToken());
				int cnt = Integer.parseInt(st.nextToken());
				int dir = Integer.parseInt(st.nextToken()) - 1;
				Micro m = new Micro(r, c, cnt, dir, i);
				micro[r][c].add(m);
				memo[i] = m;
				ans += cnt;
			}
			go(0);
			System.out.println("#" + tc + " " + ans);
		}
	}

	public static void go(int time) {
		if (time == M)
			return;

		for (int i = 0; i < K; i++) {
			if (memo[i].cnt == 0)
				continue;
			Micro m = memo[i];
			int x = m.r + dx[m.dir];
			int y = m.c + dy[m.dir];

			if (isRange(x, y)) {
				long c = m.cnt / 2;
				long diff = m.cnt - c;
				ans -= diff;
				m.cnt = c;
				if (m.cnt == 0) {
					memo[i].cnt = 0;
					micro[m.r][m.c].remove(0);
					continue;
				}
				if (m.dir == 0) {
					m.dir = 1;
				} else if (m.dir == 1) {
					m.dir = 0;
				} else if (m.dir == 2) {
					m.dir = 3;
				} else if (m.dir == 3) {
					m.dir = 2;
				}
			}
			micro[m.r][m.c].remove(0);
			m.r = x;
			m.c = y;
			micro[x][y].add(m);
		}

		chk();
		if (time < M)
			go(time + 1);
	}

	public static void chk() {
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				if (micro[i][j].size() > 1) {
					long sum = 0;
					int size = micro[i][j].size();
					Collections.sort(micro[i][j]);
					Micro biggest = micro[i][j].get(size - 1);
					int dir = biggest.dir;
					int num = biggest.num;
					while (!micro[i][j].isEmpty()) {
						Micro m = micro[i][j].get(0);
						sum += m.cnt;
						memo[m.num].cnt = 0;
						micro[i][j].remove(0);
					}
					micro[i][j].add(new Micro(i, j, sum, dir, num));
					memo[micro[i][j].get(0).num].cnt = sum;
				}
			}
		}
	}

	public static boolean isRange(int x, int y) {
		return x == 0 || y == 0 || x == N - 1 || y == N - 1;
	}
}