문제
4179번: 불!
입력의 첫째 줄에는 공백으로 구분된 두 정수 R과 C가 주어진다. 단, 1 ≤ R, C ≤ 1000 이다. R은 미로 행의 개수, C는 열의 개수이다. 다음 입력으로 R줄동안 각각의 미로 행이 주어진다. 각각의 문자
www.acmicpc.net
입력
- 입력의 첫째 줄에는 공백으로 구분된 두 정수 R과 C가 주어진다. 단, 1 ≤ R, C ≤ 1000 이다. R은 미로 행의 개수, C는 열의 개수이다.
- 다음 입력으로 R줄동안 각각의 미로 행이 주어진다.
- 각각의 문자들은 다음을 뜻한다.
- #: 벽
- .: 지나갈 수 있는 공간
- J: 지훈이의 미로에서의 초기위치 (지나갈 수 있는 공간)
- F: 불이 난 공간
- J는 입력에서 하나만 주어진다.
출력
- 지훈이가 불이 도달하기 전에 미로를 탈출 할 수 없는 경우 IMPOSSIBLE 을 출력한다.
- 지훈이가 미로를 탈출할 수 있는 경우에는 가장 빠른 탈출시간을 출력한다.
입력 예제
4 4
####
#JF#
#..#
#..#
출력 예제
3
문제 풀이
- BFS 탐색을 통해 시간별로 불을 퍼트린다.
- 불을 모두 퍼트린 후, 지훈이를 이동시키는데, 이 때, 불이 퍼져있는 곳과 벽인 곳으로 이동할 수 없으므로, 방문배열의 초기값을 0이 아닌 값으로 설정한 후, 지훈이가 이동하려는 시간보다, 불이 퍼지는 시간의 값이 더 클 때만 이동시킨다.
- 이후, 가장자리에 도달했다면, 탈출할 수 있는 경우이므로 경과시간을 출력 후 리턴하고, 가장자리에 도달하지 못했다면 "IMPOSSIBLE"을 출력한다.
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Queue;
import java.util.StringTokenizer;
public class Main {
static int n;
static int m;
static char[][] arr;
static int[][] fire;
static boolean[][] visited;
static ArrayList<int[]> f;
static int[] dy = {-1,1,0,0};
static int[] dx = {0,0,-1,1};
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
arr = new char[n][m];
fire = new int[n][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
fire[i][j] = Integer.MAX_VALUE;
}
}
visited = new boolean[n][m];
f = new ArrayList<>();
// int start_y = 0;
// int start_x = 0;
int jy = 0;
int jx = 0;
for (int i = 0; i < n; i++) {
String s = br.readLine();
for (int j = 0; j < m; j++) {
arr[i][j] = s.charAt(j);
if (arr[i][j] == 'F') {
// arr[i][j] = '.';
f.add(new int[] {i,j});
fire[i][j] = 0;
}
else if (arr[i][j] == 'J') {
jy = i;
jx = j;
}
}
}
bfs();
// print(fire);
escape(jy, jx, 1);
// print2(visited);
}
private static void escape(int jy, int jx, int time) {
Queue<int[]> queue = new ArrayDeque<>();
queue.add(new int[] {jy, jx, time});
visited[jy][jx] = true;
while (!queue.isEmpty()) {
int y = queue.peek()[0];
int x = queue.peek()[1];
int t = queue.peek()[2];
// System.out.println(y + " "+ x + " "+ t);
queue.poll();
// System.out.println(y+" "+x);
if (y == 0 || x == 0 || y == n - 1 || x == m - 1) {
System.out.println(t);
// System.out.println(y + " "+x);
return;
}
for (int d = 0; d < 4; d++) {
int ny = y + dy[d];
int nx = x + dx[d];
if (0 <= ny && ny < n && 0 <= nx && nx < m && !visited[ny][nx] && arr[ny][nx] != '#' && arr[ny][nx] != 'F' && fire[ny][nx] >= t + 1 ) {
// System.out.println(ny +" "+nx + " "+ t + 1);
visited[ny][nx] = true;
queue.add(new int[] {ny,nx, t + 1});
}
}
}
System.out.println("IMPOSSIBLE");
}
private static void bfs() {
Queue<int[]> queue = new ArrayDeque<int[]>();
for (int i = 0; i < f.size(); i++) {
int y = f.get(i)[0];
int x = f.get(i)[1];
// System.out.println(y+" "+x);
queue.add(new int[] {y,x});
}
// System.out.println(queue.size());
while (!queue.isEmpty()) {
int y = queue.peek()[0];
int x = queue.peek()[1];
queue.poll();
for (int d = 0; d < 4; d++) {
int ny = y + dy[d];
int nx = x + dx[d];
if (0 <= ny && ny < n && 0 <= nx && nx < m && arr[ny][nx] != 'F' && arr[ny][nx] != '#' && fire[ny][nx] == Integer.MAX_VALUE) {
fire[ny][nx] = fire[y][x] + 1;
queue.add(new int[] {ny,nx});
}
}
}
}
private static void print(int[][] arr) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
System.out.print(arr[i][j]+" ");
}
System.out.println();
}
}
private static void print2(boolean[][] arr) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
System.out.print(arr[i][j]+" ");
}
System.out.println();
}
}
}'Algorithm > BFS&DFS' 카테고리의 다른 글
| [Java] 백준 13165번 침투 (2) | 2023.11.02 |
|---|---|
| [Python] 백준 1240번 노드사이의 거리 (1) | 2023.11.01 |
| [Python] SWEA 2817번 부분 수열의 합 (0) | 2023.05.15 |
| [Python] SWEA 2814번 최장경로 (0) | 2023.05.15 |
| [Python] SWEA 5215번 햄버거 다이어트 (1) | 2023.05.13 |