새소식

코딩테스트/백준_골드

[C++][백준 4179] 불!

  • -

[문제]

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

 

4179번: 불!

입력의 첫째 줄에는 공백으로 구분된 두 정수 R과 C가 주어진다. 단, 1 ≤ R, C ≤ 1000 이다. R은 미로 행의 개수, C는 열의 개수이다. 다음 입력으로 R줄동안 각각의 미로 행이 주어진다.  각각의 문

www.acmicpc.net

 

[문제 풀이]

문제 조건 제한이 까다로워 실수가 많았던 문제.

BFS 에 익숙하지 않다 보니 초반에 코드가 더러워서 보기가 힘들었던 부분이 많았다.

BFS나 DFS등을 쓸 때는 변수명을 잘 지으면서 최대한 코드를 보기 편하게 만들자.

 

먼저 불꽃이 가는 곳을 모두 만들고 다음으로 지훈이를 옮기자.

* 팁 : 불꽃이 가는 곳은 기본 미로가 아닌 다른 불꽃 미로를 만들어두자. 안 그러면 나중에 지훈이가 미로를 돌아다닐때 비교하기가 힘들어진다. 나중에 익숙해지면 미로 하나에 넣을 수 있을테지만 우선은 따로 만들어서 연습을 해보자.

 

[새로 배운 문법]

pair<pair<int,int>, int>

pair 안에 pair를 놨둠으로서 tuple을 대신 할 수 있다.

gcc 11 이하의 경우에는 tuple을 사용할 수 없으니 해당 방법을 익혀두는 것도 나쁘지 않을 것.

[코드]

#include<iostream>
#include<queue>
#include<vector>
#define endl "\n"

using namespace std;

int fire_visit[1001][1001];

void fire_bfs(vector<vector<char> >& maze, queue<pair<int, int> > fire, int r, int c){
    fire_visit[fire.front().first][fire.front().second] = 0;
    int dict[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};

    while(fire.size()>0){
        int fire_size = fire.size();
        while(fire_size--){
            
            int fire_x = fire.front().first;
            int fire_y = fire.front().second;
            fire.pop();

            for(int i = 0;i<4;i++){
                int next_x = fire_x + dict[i][0];
                int next_y = fire_y + dict[i][1];

                if(next_x >= 0 and next_x < r and next_y >= 0 and next_y < c){
                    if(maze[next_x][next_y] != '#'){
                        if(fire_visit[next_x][next_y] > fire_visit[fire_x][fire_y] + 1){
                            fire_visit[next_x][next_y] = fire_visit[fire_x][fire_y] + 1;
                            fire.push(make_pair(next_x, next_y));
                        }
                    }
                }
            }
        }
    }
    return;
}

int bfs(vector<vector<char> > maze, queue<pair<pair<int, int>, int > > jihhon, int r, int c){
    vector<vector<int> > visit(r, vector<int>(c, 0));
    visit[jihhon.front().first.first][jihhon.front().first.second] = 1;

    int dict[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};

    while(jihhon.size()>0){

            // cout<<"jihoon_x : "<<jihhon.front().first.first<<endl;
            // cout<<"jihoon_y ; "<<jihhon.front().first.second<<endl;

            int jihoon_x = jihhon.front().first.first;
            int jihoon_y = jihhon.front().first.second;
            int jihoon_num = jihhon.front().second;
            jihhon.pop();

            if(jihoon_x == 0 or jihoon_x == r-1 or jihoon_y == 0 or jihoon_y == c-1){
                return jihoon_num + 1;
            }

            for(int i = 0;i<4;i++){
                int next_x = jihoon_x + dict[i][0];
                int next_y = jihoon_y + dict[i][1];

            if(next_x >= 0 and next_x <r and next_y >= 0 and next_y < c){
                if(visit[next_x][next_y] == 0){
                    if(fire_visit[next_x][next_y] > jihoon_num + 1 and maze[next_x][next_y] != '#'){
                        visit[next_x][next_y] = 1;
                        jihhon.push(make_pair(make_pair(next_x, next_y), jihoon_num + 1));
                    }
                }
            }
        }        
    }

    return 0 ;
}

int main(){
    
    int r, c;
    cin>>r>>c;

    vector<vector<char> > maze(r, vector<char>(c,0));
    queue<pair<pair<int, int>,int> > jihoon;
    queue<pair<int ,int> > fire;

    for(int i = 0;i<r;i++){
        for(int j = 0;j<c;j++){
            cin>>maze[i][j];
            if(maze[i][j] == 'J'){
                jihoon.push(make_pair(make_pair(i,j),0));
            }
            else if(maze[i][j] == 'F'){
                fire.push(make_pair(i,j));
                fire_visit[i][j] = 0;
            }
            else{
                fire_visit[i][j] = 9999;
            }
        }
    }

    if(fire.size() > 0){
        fire_bfs(maze,fire,r,c);
    }
    
    int answer = bfs(maze,jihoon,r,c);

    if(answer > 0){
        cout<<answer<<endl;
    }
    else{
        cout<<"IMPOSSIBLE"<<endl;
    }

    return 0;
}
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.