Algorithm/BOJ
BOJ 4179 불!
wow
2021. 3. 28. 15:55
4179번: 불!
입력의 첫째 줄에는 공백으로 구분된 두 정수 R과 C가 주어진다. 단, 1 ≤ R, C ≤ 1000 이다. R은 미로 행의 개수, C는 열의 개수이다. 다음 입력으로 R줄동안 각각의 미로 행이 주어진다. 각각의 문
www.acmicpc.net
문제 분석
- 기존에 풀었던 BOJ 5427 불 문제와 똑같은 문제다.
- bfs로 탐색하면서 불을 지르고, 지훈이를 이동시킨다.
- 각각의 좌표를 따로 관리하면서 지훈이가 탈출할 수 있도록 한다.
문제 풀이
1) 불의 좌표와 지훈이의 좌표를 각각의 덱에 받아온다.
2) bfs를 통해 불-> 지훈이순서로 탐색을 한다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Deque;
import java.util.StringTokenizer;
public class Main {
private static int R, C, ans;
private static int[] dr = { -1, 1, 0, 0 }; // 상하좌우 행
private static int[] dc = { 0, 0, -1, 1 }; // 상하좌우 열
private static char[][] map;
private static boolean[][] visited;
private static Deque<firePoint> fireDq; // 불의 좌표값 저장하는 큐
private static Deque<jihunPoint> jihunDq; // 지훈이의 좌표값 저장하는 큐
public static void main(String[] args) throws Exception {
input();
}// main
private static void input() throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
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];
jihunDq = new ArrayDeque<>();
fireDq = new ArrayDeque<>();
for (int i = 0; i < R; i++) {
String s = br.readLine();
for (int j = 0; j < C; j++) {
char ch = s.charAt(j);
map[i][j] = ch;
if (ch == 'J') {
jihunDq.add(new jihunPoint(i, j, 0));
visited[i][j] = true;
map[i][j] = '.';
}
if (ch == 'F')
fireDq.add(new firePoint(i, j));
}
} // 좌표값 입력
ans = bfs();
if (R == 1 && C == 1) {
ans = 0;
}
System.out.println(ans == -1 ? "IMPOSSIBLE" : ans);
}// input
private static int bfs() {
while (!jihunDq.isEmpty()) {
int size = fireDq.size();
// 일단 불을 지르자.
for (int i = 0; i < size; i++) {
firePoint cur = fireDq.poll();
int r = cur.x;
int c = cur.y;
for (int d = 0; d < 4; d++) {
int nr = r + dr[d];
int nc = c + dc[d];
if (nr < 0 || nc < 0 || nr > R-1 || nc > C-1)
continue;
if (map[nr][nc] == '.') {
map[nr][nc] = 'F';
fireDq.add(new firePoint(nr, nc));
}
}
}
size = jihunDq.size();
// 지훈이 이동시키고 그 자리가 불나면 종료, 불이 아니면 이동시키기.
for (int i = 0; i < size; i++) {
jihunPoint cur = jihunDq.poll();
int r = cur.x;
int c = cur.y;
int time = cur.depth;
if (r == 0 || c == 0 || r == R - 1 || c == C - 1) { // 지훈이가 탈출했을 경우
ans = time + 1;
return ans;
}
for (int d = 0; d < 4; d++) {
int nr = r + dr[d];
int nc = c + dc[d];
if (nr < 0 || nc < 0 || nr > R-1 || nc > C-1)
continue;
if (visited[nr][nc])
continue;
if (map[nr][nc] == '.') {
visited[nr][nc] = true;
jihunDq.add(new jihunPoint(nr, nc, time + 1));
}
}
}
}
return -1;
}// bfs
static class jihunPoint {
int x;
int y;
int depth;
public jihunPoint(int x, int y, int depth) {
super();
this.x = x;
this.y = y;
this.depth = depth;
}
}// jihunPoint-class
static class firePoint {
int x;
int y;
public firePoint(int x, int y) {
super();
this.x = x;
this.y = y;
}
}// firePoint-class
}// class-End