[백준] 불!

유승선 ·2022년 8월 18일
1

백준

목록 보기
46/64

조금 변형된 유형의 문제를 찾아서 풀어봤다. 솔직히 이제 백준 그래프 추천 문제는 정말로 많이 풀게 된거같다. 이번 문제도 큰 문제없이 한번에 통과 됐고 설명에 대한 해석만 본 후에 잘 풀었다. 일반적으로 시뮬레이션이 섞인 BFS 탐색 문제에서 두 물체가 움직이게 되면 하나가 먼저 움직이고 다른 하나가 움직이기 나름인데 이 문제는 특이하게도 지훈이라는 캐릭터와 불이 난 공간이 동시에 움직여야 했다.

그러나 여기서 가장 고려해볼점은 지훈이는 절대로 불이 있는 곳으로 움직이지 못하지만 불은 움직이는데 벽 말고는 제한이 없단것이다. 그래서 내가 생각했던것은, 지훈이를 무시한채로 불을 먼저 움직이고 visited 벡터를 불과 지훈이한테 따로 만들어줘서 탐색하자 였다. 만약에 지훈이가 움직일 수 있는 공간이 없어지면 그 말은 탈출을 못했단 소리이기 때문에 IMPOSSIBLE 을 출력해줬다.

#include <iostream> 
#include <bits/stdc++.h> 
#define endl "\n"
#define MAX 100010
using namespace std;

int R, C; 
char matrix[1001][1001]; 
bool Jihoon[1001][1001];
bool Fire[1001][1001]; 
vector<pair<int,int>> dir = {{0,1},{0,-1},{1,0},{-1,0}}; 

struct Ji{
    int x, y, dist; 
};

void Input(){
    cin >> R >> C; 
    for(int i = 0; i < R; i++){
        for(int j = 0; j < C; j++){
            cin >> matrix[i][j]; 
        }
    }

}

void Solution(){
    queue<pair<int,int>> fireQ; 
    queue<Ji> JihoonQ; 

    for(int i = 0; i < R; i++){
        for(int j = 0; j < C; j++){
            if(matrix[i][j] == 'F'){
                Fire[i][j] = true; 
                fireQ.push({i,j}); 
            }
            if(matrix[i][j] == 'J'){
                Jihoon[i][j] = true; 
                JihoonQ.push({i,j,0}); 
            }
        }
    }

    while(!JihoonQ.empty()){
        int size1 = fireQ.size();
        int size2 = JihoonQ.size();
        for(int i = 0; i < size1; i++){
            pair<int,int> first = fireQ.front(); 
            fireQ.pop(); 

            int x = first.first, y = first.second; 

            for(pair<int,int>& p : dir){
                int nX = x + p.first;
                int nY = y + p.second; 

                if(nX < 0 || nY < 0 || nX >= R || nY >= C || matrix[nX][nY] == '#' || Fire[nX][nY]) continue;

                Fire[nX][nY] = true;
                fireQ.push({nX,nY}); 
            }
        }

        for(int j = 0; j < size2; j++){
            Ji second = JihoonQ.front();
            JihoonQ.pop(); 

            int xx = second.x, yy = second.y, dist = second.dist; 

            if(xx == R-1 || xx == 0 || yy == C-1 || yy == 0){
                cout << dist + 1; 
                return; 
            }

            for(pair<int,int>& p : dir){
                int nXX = xx + p.first;
                int nYY = yy + p.second;

                if(nXX < 0 || nYY < 0 || nXX >= R || nYY >= C || matrix[nXX][nYY] == '#' || Jihoon[nXX][nYY] || Fire[nXX][nYY]) continue;

                Jihoon[nXX][nYY] = true; 
                JihoonQ.push({nXX,nYY,dist+1}); 
            }
        }
        
    }

    cout << "IMPOSSIBLE"; 
}


void Solve(){
    Input();
    Solution(); 
}

int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    //freopen("input.txt", "r", stdin);
    Solve();
    return 0;

}

하나의 while 문에서 두가지에 큐를 동시에 적은적은 처음이기에 그래도 재밌게 풀었지만 문제 설명을 좀 더 잘해줬으면 하는 바램은 있다.

배운점
1. 시뮬레이션 BFS.
2. 여러가지 visited 배열을 활용하자.

profile
성장하는 사람

0개의 댓글