https://www.acmicpc.net/problem/19237
정답 코드
import java.awt.Point;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.PriorityQueue;
import java.util.StringTokenizer;
public class Main {
static int N, M, K;
static int[][][] board;
static int[][][] direction;
static int[][] sharks;
static boolean[] alive;
static int step = 0;
static ArrayDeque<int[]> smell = new ArrayDeque<>();
static int[] di = { 0, -1, 1, 0, 0 };
static int[] dj = { 0, 0, 0, -1, 1 };
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
K = Integer.parseInt(st.nextToken());
board = new int[N][N][2];
direction = new int[M + 1][5][5];
sharks = new int[M + 1][3];
alive = new boolean[M + 1];
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < N; j++) {
int number = Integer.parseInt(st.nextToken());
if (number != 0) {
sharks[number][0] = i;
sharks[number][1] = j;
alive[number] = true;
}
}
}
st = new StringTokenizer(br.readLine());
for (int number = 1; number < M + 1; number++) {
sharks[number][2] = Integer.parseInt(st.nextToken());
}
for (int number = 1; number < M + 1; number++) {
for (int i = 1; i < 5; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 1; j < 5; j++) {
direction[number][i][j] = Integer.parseInt(st.nextToken());
}
}
}
spreadSmell();
while (!allDied() && step <= 1000) {
// 시작 위치에 냄새 뿌림
for (int time = 0; time < K; time++) {
if (allDied()) {
break;
}
moveShark();
step++;
}
}
if (step > 1000) {
System.out.println(-1);
} else {
System.out.println(step);
}
}
private static void moveShark() {
ArrayDeque<int[]> queue = new ArrayDeque<>();
// 갈 좌표 체크하고
for (int number = 1; number < M + 1; number++) {
if (!alive[number])
continue;
int[] info = sharks[number];
int ci = info[0];
int cj = info[1];
int cd = info[2];
boolean moved = false;
for (int i = 1; i < 5; i++) {
int d = direction[number][cd][i];
int ni = ci + di[d];
int nj = cj + dj[d];
if (validate(ni, nj)) {
if (board[ni][nj][1] == 0) {
queue.offer(new int[] { number, ni, nj, d });
moved = true;
break;
}
}
}
if (!moved) {
for (int i = 1; i < 5; i++) {
int d = direction[number][cd][i];
int ni = ci + di[d];
int nj = cj + dj[d];
if (validate(ni, nj)) {
if (board[ni][nj][0] == number) {
queue.offer(new int[] { number, ni, nj, d });
break;
}
}
}
}
}
decreaseSmell();
while (!queue.isEmpty()) {
int[] info = queue.poll();
int number = info[0];
sharks[number][0] = info[1];
sharks[number][1] = info[2];
sharks[number][2] = info[3];
}
deleteDuplicated();
spreadSmell();
}
private static boolean validate(int ni, int nj) {
return 0 <= ni && ni < N && 0 <= nj && nj < N;
}
private static void deleteDuplicated() {
HashMap<Point, PriorityQueue<Integer>> pq = new HashMap<>();
for (int number = 1; number < M + 1; number++) {
if (!alive[number])
continue;
int si = sharks[number][0];
int sj = sharks[number][1];
pq.putIfAbsent(new Point(si, sj), new PriorityQueue<>());
pq.get(new Point(si, sj)).offer(number);
}
for (Entry<Point, PriorityQueue<Integer>> entry : pq.entrySet()) {
PriorityQueue<Integer> queue = entry.getValue();
Integer smallest = null;
while (!queue.isEmpty()) {
Integer current = queue.poll();
if (alive[current]) {
smallest = current;
break;
}
}
if (smallest != null) {
alive[smallest] = true;
}
while (!queue.isEmpty()) {
Integer number = queue.poll();
if (alive[number]) {
alive[number] = false;
}
}
}
}
private static void decreaseSmell() {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (board[i][j][1] > 0) {
board[i][j][1]--;
}
if (board[i][j][1] == 0) {
board[i][j][0] = 0;
}
}
}
}
private static void spreadSmell() {
for (int number = 1; number < M + 1; number++) {
if (alive[number]) {
board[sharks[number][0]][sharks[number][1]][0] = number;
board[sharks[number][0]][sharks[number][1]][1] = K;
smell.offer(new int[] { sharks[number][0], sharks[number][1], K });
}
}
}
private static boolean allDied() {
for (int i = 2; i < M + 1; i++) {
if (alive[i]) {
return false;
}
}
return true;
}
}
'PS > 백준' 카테고리의 다른 글
[백준] 17472번 다리 만들기 2 (Java) (0) | 2025.02.16 |
---|---|
[백준] 17837번 새로운 게임 2 (python) (0) | 2025.02.12 |
[백준] 2146번 다리 만들기 (python) (0) | 2025.01.09 |
[백준] 7576번 토마토 (python) (0) | 2024.12.30 |
[백준] 1600번 말이 되고픈 원숭이 (python) (0) | 2024.12.30 |