미생물격리
in Algorithm on SW Expert Academy
Software Expert Academy [2382] 미생물격리
소스코드
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;
}
}