백준 4179 불

JunSeok·2023년 2월 13일
0

백준

목록 보기
14/40

BFS 문제이다.
불의 전파를 먼저 DFS를 돌리고 지훈이 이동 DFS를 돌린다는 핵심은 알았지만 불을 피하는 조건문이 조금 까다로웠고 지훈이의 탈출 조건을 생각하지 못했다..

핵심을 찾아내기 어려운 문제는 아니었다.
구현력을 더 늘리자

지훈이의 탈출 조건은 좌표를 벗어나는 것

/*
- 행과 열이 주어지고 string으로 board가 주어진다.
- 불과 지훈이 각각 DFS를 돌린다.
    - 불과 지훈이 DFS 돌리는 것이 서로 상호관계가 있는 것이 아니기 때문에 동시 진행 가능
    - 서로 영향을 끼치는 경우 이 방법 사용 불가
- 시작지점은 0이니 헷갈리지 않게 -1로 fill해준다.
- 지훈이 탈출 암시 상황은 좌표를 벗어나는 상황
*/

#include <bits/stdc++.h>
using namespace std;
#define X first
#define Y second
string board[1002];
int n, m;
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
int fire[1002][1002]; // 불 DFS
int person[1002][1002]; // 지훈 DFS

int main(void) {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> n >> m;
    for(int i = 0; i < n; i++) {
        fill(fire[i], fire[i]+m, -1);
        fill(person[i], person[i]+m, -1);
    }
    for(int i = 0; i < n; i++) {
        cin >> board[i];
    }
    queue<pair<int, int>> FQ; // 불 좌표
    queue<pair<int, int>> PQ; // 사람 좌표
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < m; j++) {
            if(board[i][j] == 'F') {
                FQ.push({i, j});
                fire[i][j] = 0;
            }
            if(board[i][j] == 'J') {
                PQ.push({i, j});
                person[i][j] = 0;
            }
        }
    }

    // 불 전파
    while(!FQ.empty()) {
        auto cur = FQ.front(); FQ.pop();
        for(int dir = 0; dir < 4; dir++) {
            int nx = cur.X + dx[dir];
            int ny = cur.Y + dy[dir];
            if(nx < 0 || nx >= n || ny < 0 || ny >= m) continue;
            if(board[nx][ny] == '#' || fire[nx][ny] >= 0) continue;
            fire[nx][ny] = fire[cur.X][cur.Y]+1;
            FQ.push({nx, ny});
        }
    }

    // 지훈이 이동
    while(!PQ.empty()) {
        auto cur = PQ.front(); PQ.pop();
        for(int dir = 0; dir < 4; dir++) {
            int nx = cur.X + dx[dir];
            int ny = cur.Y + dy[dir];
            // 좌표밖으로 나간 경우 탈출 성공 의미
            if(nx < 0 || nx >= n || ny < 0 || ny >= m) {
                cout << person[cur.X][cur.Y]+1;
                return 0;
            }
            if(board[nx][ny] == '#' || person[nx][ny] >= 0) continue;
            // fire은 -1로 fill 해줬기 때문에 구분 필요
            if(fire[nx][ny] != -1 && fire[nx][ny] <= person[cur.X][cur.Y]+1) continue;
            person[nx][ny] = person[cur.X][cur.Y]+1;
            PQ.push({nx, ny});
        }
    }
    cout << "IMPOSSIBLE";
}
profile
최선을 다한다는 것은 할 수 있는 한 가장 핵심을 향한다는 것

0개의 댓글