본문 바로가기
백준

백준 5427 불

by 콩순이냉장고 2020. 7. 20.

문제 URL : https://www.acmicpc.net/problem/5427

문제 접근법:

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
#include <iostream>
#include <queue>
using namespace std;
char map[1000][1000];
int w, h;//가로 세로
int sy, sx;//출발점
int dy[4= { -1010 };
int dx[4= { 010-1 }; //방향
int visit[1000][1000];
bool isrange(int y, int x){//범위 안에 있는지 확인
    if (0 <= y&&< h && 0 <= x&&< w)
        return true;
    return false;
}
struct coordinate{
    int y, x, cost;
    coordinate(int y, int x, int cost) :y(y), x(x), cost(cost){}
};
void init(){
    for (int i = 0; i < h; i++)
    {
        for (int j = 0; j < w; j++)
        {
            visit[i][j] = 0;
        }
    }
}
 
int bfs(vector<pair<intint>> &fire){
    queue<coordinate> q, fq;//상근이가 이동하기위한 자료형구조 q 불이 번지기위한 fq
    q.push({ sy, sx, 1 });
    visit[sy][sx] = 1;
    for (int i = 0; i < fire.size(); i++)//불의좌표를 fq에넣음
        fq.push({ fire[i].first, fire[i].second, 1 });
    while (!fq.empty() || !q.empty())//
    {
        int fqsize = fq.size();//불을 먼저 퍼트리기
        while (fqsize--){
            int y = fq.front().y;
            int x = fq.front().x;
            fq.pop();
            for (int i = 0; i < 4; i++)
            {
                int ny = y + dy[i];
                int nx = x + dx[i];
                if (isrange(ny, nx) && map[ny][nx] == '.')//빈공간만 불을 번지게함
                {
                    fq.push({ ny, nx, 1 });
                    map[ny][nx] = '*';
                }
            }
        }
        int qsize = q.size();//불이 번졌다면 상근이를 움직이게함
        while (qsize--){
            int y = q.front().y;
            int x = q.front().x;
            int cost = q.front().cost;
            if (y == h - 1 || y == 0 || x == w - 1 || x == 0)//도착지점
                return cost;
            q.pop();
            for (int i = 0; i < 4; i++)
            {
                int ny = y + dy[i];
                int nx = x + dx[i];
                if (isrange(ny, nx) && map[ny][nx] == '.'&&visit[ny][nx] == 0)
                {
                    q.push({ ny, nx, cost + 1 });
                    visit[ny][nx] = 1;
                }
            }
        }
 
    }
 
    return -1;//실패
}
 
int main(void)
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int test;
    cin >> test;
    while (test--){
        cin >> w >> h;
        vector<pair<intint>> fire;
        init();
        for (int i = 0; i < h; i++)
        {
            for (int j = 0; j < w; j++)
            {
                cin >> map[i][j];
                if (map[i][j] == '@')//상근이가 있는위치를 저장해주고 그자리를 .으로 바꿈
                {
                    sy = i;
                    sx = j;
                    map[i][j] == '.';
                }
                else if (map[i][j] == '*'){//불의 좌표들을 벡터로 저장
                    fire.push_back({ i, j });
                }
            }
        }
        int result = bfs(fire);
        if (result == -1)
            cout << "IMPOSSIBLE\n";
        else
            cout << result << "\n";
    }
 
}
 
 
cs

코드를 보면 직관적으로 바로 이해하실수 있을거라 생각합니다.

이해가 안되는점이나 궁금한점이 있다면 언제든지

댓글을 달아주세요 ㅎㅎ

 

'백준' 카테고리의 다른 글

백준 1890 점프  (0) 2020.07.22
백준 17830 이진수씨의 하루 일과  (0) 2020.07.22
백준 2630 색종이 만들기  (0) 2020.07.20
백준 1992 쿼드트리  (0) 2020.07.20
백준 1456 거의 소수  (0) 2020.07.20