반응형
개인적인 풀이일 뿐, 최적의 정답이 아님을 알려드립니다.
문제
난이도: 골드 4
사용언어: JAVA
풀이
기본적으로는 BFS를 이용해 문제를 해결할 수 있습니다. 단지 불과 상근이의 위치를 모두 탐색해 주어야 하므로, 큐와 BFS 함수를 따로따로 만들어주었습니다. BFS에 관한 설명은 아래 문제의 풀이에서 확인하실 수 있습니다.
불은 빈칸이거나 상근이가 있는 칸으로는 옮겨갈 수 있습니다. (상근이는 불이 오자마자 피할 수 있기 때문에) 그리고 상근이는 빈칸으로만 옮겨갈 수 있습니다. 이렇게 BFS를 반복 수행하여 상근이가 탈출을 할 수 있는지만 확인해주면 됩니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
import java.io.*;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
class Main {
static class position {
int x;
int y;
}
static int w, h;
static int[][] d = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; // 불과 상근이가 움직일 수 있는 좌표 (상,하,좌,우)
static int cnt = 0;
static int flag = 0;
static Queue<position> q_human = new LinkedList<>(); // 상근이의 움직임을 저장할 큐
static Queue<position> q_fire = new LinkedList<>(); // 불의 움직임을 저장할 큐
public static void bfs_fire(int x, int y, char arr[][]) { // 불의 움직임을 위한 bfs 함수
int i;
for (i = 0; i < 4; i++) {
if (arr[x + d[i][0]][y + d[i][1]] == '.' || arr[x + d[i][0]][y + d[i][1]] == '@') { // 빈 칸이거나 상근이가 있는 칸이면
position p = new position();
p.x = x + d[i][0];
p.y = y + d[i][1];
arr[x + d[i][0]][y + d[i][1]] = '*'; // 해당 좌표를 불로 표시해주고
q_fire.add(p); // 큐에 삽입
}
}
}
public static void bfs_human(int x, int y, char arr[][]) { // 상근이의 움직임을 위한 bfs 함수
int i;
for (i = 0; i < 4; i++) {
if (arr[x + d[i][0]][y + d[i][1]] == '.') { // 빈칸이면
position p = new position();
p.x = x + d[i][0];
p.y = y + d[i][1];
arr[x + d[i][0]][y + d[i][1]] = '@'; // 해당 좌표를 상근이로 표시해주고
q_human.add(p); // 큐에 삽입
}
if (arr[x + d[i][0]][y + d[i][1]] == 0) { // 만약 탈출을 했다면
System.out.println(cnt + 1); // 횟수 출력
flag = 1; // 반복문 종료를 위한 flag
break;
}
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int T = Integer.parseInt(br.readLine());
int l;
for (l = 0; l < T; l++) { // 테스트 케이스 갯수만큼
String s = br.readLine();
StringTokenizer st = new StringTokenizer(s);
w = Integer.parseInt(st.nextToken());
h = Integer.parseInt(st.nextToken());
char[][] arr = new char[h + 2][w + 2];
int i, j, k;
for (i = 1; i <= h; i++) { // 테이블 입력
s = br.readLine();
for (j = 1; j <= w; j++) {
arr[i][j] = s.charAt(j - 1);
}
}
for (i = 1; i <= h; i++) {
for (j = 1; j <= w; j++) {
if (arr[i][j] == '@') { // 상근이의 위치를 큐에 삽입
position p_human = new position();
p_human.x = i;
p_human.y = j;
q_human.add(p_human);
} else if (arr[i][j] == '*') { // 불의 위치를 큐에 삽입
position p_fire = new position();
p_fire.x = i;
p_fire.y = j;
q_fire.add(p_fire);
}
}
}
while (true) {
k = q_fire.size();
position p_fire = new position();
for (i = 0; i < k; i++) { // 불의 위치 이동을 위한 bfs 수행
p_fire = q_fire.remove();
bfs_fire(p_fire.x, p_fire.y, arr);
}
k = q_human.size();
if (k == 0) { // 상근이가 더 이상 움직일 수 있는 곳이 없다면
System.out.println("IMPOSSIBLE"); // 탈출 불가능
break;
}
position p_human = new position();
for (i = 0; i < k; i++) { // 상근이의 위치 이동을 위한 bfs 수행
p_human = q_human.remove();
bfs_human(p_human.x, p_human.y, arr);
if (flag == 1) // 이미 탈출 했다면 반복문 탈출
break;
}
if (flag == 1) // 이미 탈출 했다면 반복문 탈출
break;
cnt++;
}
q_fire.clear(); // 큐 및 변수들 초기화
q_human.clear();
flag = 0;
cnt = 0;
}
}
}
|
cs |
반응형
'백준 온라인 저지 > Gold' 카테고리의 다른 글
[BOJ] 2206 - 벽 부수고 이동하기 (0) | 2021.02.22 |
---|---|
[BOJ] 2352 - 반도체 설계 (0) | 2021.02.22 |
[BOJ] 1806 - 부분합 (0) | 2021.02.21 |
[BOJ] 2056 - 작업 (0) | 2021.02.21 |
[BOJ] 1915 - 가장 큰 정사각형 (0) | 2021.02.20 |