https://www.acmicpc.net/problem/4179

 

4179번: 불!

입력의 첫째 줄에는 공백으로 구분된 두 정수 R과 C가 주어진다. 단, 1 ≤ R, C ≤ 1000 이다. R은 미로 행의 개수, C는 열의 개수이다. 다음 입력으로 R줄동안 각각의 미로 행이 주어진다.  각각의 문

www.acmicpc.net

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main {

	// 상하좌우
	static int[] dr = { -1, 1, 0, 0 };
	static int[] dc = { 0, 0, -1, 1 };

	static int R, C, answer;
	static char[][] map;

	// 지훈이가 방문했는지 확인
	static boolean[][] visited;

	// 지훈이 위치 정보
	static Queue<Pos> jihunQ = new LinkedList<>();

	// 불 위치 정보
	static Queue<Pos> fireQ = new LinkedList<>();

	static class Pos {
		int r, c;

		public Pos(int r, int c) {
			this.r = r;
			this.c = c;
		}
	}

	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());

		R = Integer.parseInt(st.nextToken());
		C = Integer.parseInt(st.nextToken());
		map = new char[R][C];
		visited = new boolean[R][C];

		for (int i = 0; i < R; i++) {
			String str = br.readLine();
			for (int j = 0; j < C; j++) {
				map[i][j] = str.charAt(j);

				// 지훈이인 경우 위치 정보 담기
				if (map[i][j] == 'J') {
					map[i][j] = '.';
					jihunQ.offer(new Pos(i, j));
				}
				// 불인 경우 위치 정보 담기
				else if (map[i][j] == 'F') {
					fireQ.offer(new Pos(i, j));
				}
			}
		}

		Pos curr;
		int r, c, nr, nc, size;

		while (!jihunQ.isEmpty()) {
			// fire
			// size만큼 불 사방으로 번짐
			size = fireQ.size();
			while (size-- > 0) {
				curr = fireQ.poll();
				r = curr.r;
				c = curr.c;
				for (int dir = 0; dir < 4; dir++) {
					nr = r + dr[dir];
					nc = c + dc[dir];

					// 경계 안에 있고 .인 경우
					if (isRange(nr, nc) && map[nr][nc] == '.') {
						// map에 F로 표시하고 불 위치 정보 추가
						map[nr][nc] = 'F';
						fireQ.offer(new Pos(nr, nc));
					}
				}
			}

			// jihun
			// size만큼 지훈이 이동
			size = jihunQ.size();
			while (size-- > 0) {
				curr = jihunQ.poll();
				r = curr.r;
				c = curr.c;
				// 지훈 위치 방문 체크
				visited[r][c] = true;

				for (int dir = 0; dir < 4; dir++) {
					nr = r + dr[dir];
					nc = c + dc[dir];

					// 경계 벗어나는 경우: 탈출
					if (!isRange(nr, nc)) {
						// 다음 턴에 나오는 것이므로 ++answer
						System.out.println(++answer);
						return;
					}
					// 경계 내에 있는 경우
					else {
						// 갈 수 있고 아직 방문하지 않았다면
						if (map[nr][nc] == '.' && !visited[nr][nc]) {
							// 지훈이 위치 정보 추가
							jihunQ.offer(new Pos(nr, nc));
							// 방문 체크
							visited[nr][nc] = true;
						}
					}
				}
			}

			// 이동이 성공한 경우
			answer++;
		}

		// while에서 answer 출력하지 않은 경우: IMPOSSIBLE
		System.out.println("IMPOSSIBLE");
	}

	private static boolean isRange(int r, int c) {
		// 경계 체크

		return (r >= 0 && r < R && c >= 0 && c < C);
	}
}

+ Recent posts