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

 

5427번: 불

문제 상근이는 빈 공간과 벽으로 이루어진 건물에 갇혀있다. 건물의 일부에는 불이 났고, 상근이는 출구를 향해 뛰고 있다. 매 초마다, 불은 동서남북 방향으로 인접한 빈 공간으로 퍼져나간다. 벽에는 불이 붙지 않는다. 상근이는 동서남북 인접한 칸으로 이동할 수 있으며, 1초가 걸린다. 상근이는 벽을 통과할 수 없고, 불이 옮겨진 칸 또는 이제 불이 붙으려는 칸으로 이동할 수 없다. 상근이가 있는 칸에 불이 옮겨옴과 동시에 다른 칸으로 이동할 수 있다. 빌딩

www.acmicpc.net

4179번 불! (문제 링크) 문제와 스토리가 비슷한 문제인 것 같다.  (4179 불! 풀이 링크)

이 문제는 테스트 케이스가 최대 100개로 여러 개 있기 때문에 매번의 테스트 케이스에서 배열과, 큐 등 초기화를 잘해주어야 한다.

 

 

 

상근이가 최단 시간으로 탈출하는 경우와 불이 퍼지는 것을 구현하기 위해 BFS를 사용한다.

BFS는 상근이가 이동할 수 있는 곳이 더 없다면 끝나기 때문에 상근이의 좌표를 담은 큐가 비었다면 종료한다.

또는, 탈출에 성공한 경우에 바로 탐색을 종료한다.

 

 

 

큐 2개를 사용하여 상근이와 불의 위치를 각각의 큐에 넣어주고 각각 BFS를 진행한다. 같은 시간 동안 불을 먼저 이동시키고 상근이를 이동시키면 불이 확산되지 않은 곳으로 이동할 수 있다. 매 초마다 불을 먼저 확산시키고 다음에 상근이를 이동시키기 위해서 각자의 큐 사이즈만큼씩만 진행하면 된다. 한 번에 이동할 수 있는 위치만큼(현재 위치로부터 1만큼 이동한 곳)이 큐에 새로 들어가기 때문이다.

 

 

 

상근이가 빌딩 지도 범위를 넘어가면 탈출에 성공한 것이므로 바로 true를 리턴하여 시간을 출력해준다.

BFS가 끝났는데 빌딩을 탈출하지 못했다면 false를 리턴하고 문제 조건에 따라 IMPOSSIBLE을 출력한다.

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
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
 
int h, w, time;
char map[1000][1000];
bool visit[1000][1000];
 
queue<pair<intint> > sq; //상근이 이동 큐
queue<pair<intint> > fq; //불 이동 큐
 
int dx[] = { 0,0,1,-1 };
int dy[] = { 1,-1,0,0 };
 
bool bfs() {
    time = 0;
 
    while (!sq.empty()) {
        int fqsize = fq.size();
        int sqsize = sq.size();
        int x, y, nx, ny;
 
        time++;
 
        //불 이동
        while (fqsize--) {
            x = fq.front().first;
            y = fq.front().second;
            fq.pop();
            for (int k = 0; k < 4; k++) {
                nx = x + dx[k];
                ny = y + dy[k];
                //범위 체크
                if (nx < 0 || ny < 0 || nx >= h || ny >= w) continue;
                //벽
                if (map[nx][ny] == '#'continue;
                //방문 체크
                if (visit[nx][ny]) continue;
 
                fq.push({ nx,ny });
                visit[nx][ny] = true;
            }
        }
 
        //상근이 이동
        while (sqsize--) {
            x = sq.front().first;
            y = sq.front().second;
            sq.pop();
            for (int k = 0; k < 4; k++) {
                nx = x + dx[k];
                ny = y + dy[k];
                if (nx < 0 || ny < 0 || nx >= h || ny >= w) {
                    //탈출 성공
                    return true;
                }
                //벽
                if (map[nx][ny] == '#'continue;
                //방문 체크
                if (visit[nx][ny]) continue;
 
                sq.push({ nx,ny });
                visit[nx][ny] = true;
            }
        }
    }
 
 
//탈출 실패
    return false;
}
 
 
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
 
    int T;
    cin >> T;
 
    while (T--) {        
        //다음 테스트 케이스를 위해 초기화
        memset(visit, falsesizeof(visit));
        while (!fq.empty()) fq.pop();
        while (!sq.empty()) sq.pop();
        bool exitFlag = false;
 
 
        cin >> w >> h;
        for (int i = 0; i < h; i++) {
            for (int j = 0; j < w; j++) {
                cin >> map[i][j];
                if (map[i][j] == '@') {
                    sq.push({ i,j });
                    map[i][j] = '.';
                    visit[i][j] = true;
                }
                else if (map[i][j] == '*') {
                    fq.push({ i,j });
                    visit[i][j] = true;
                }
            }
        }
 
 
        bool result = bfs();
 
        if (result) cout << time << '\n';
        else cout << "IMPOSSIBLE" << "\n";
    }
 
    return 0;
}
Colored by Color Scripter
 

'BOJ' 카테고리의 다른 글

[BOJ] 10711. 모래성  (0) 2020.04.27
[BOJ] 2866. 문자열 잘라내기  (0) 2020.04.21
[BOJ] 18809. Gaaaaaaaaaarden  (0) 2020.03.23
[BOJ] 18808. 스티커 붙이기  (0) 2020.03.23
[BOJ] 17822. 원판 돌리기  (0) 2020.03.16

+ Recent posts