본문 바로가기
Algorythms

백준 5427번 풀이 c++ and java

by 준형코딩 2023. 7. 21.

문제

상근이는 빈 공간과 벽으로 이루어진 건물에 갇혀있다. 건물의 일부에는 불이 났고, 상근이는 출구를 향해 뛰고 있다.

매 초마다, 불은 동서남북 방향으로 인접한 빈 공간으로 퍼져나간다. 벽에는 불이 붙지 않는다. 상근이는 동서남북 인접한 칸으로 이동할 수 있으며, 1초가 걸린다. 상근이는 벽을 통과할 수 없고, 불이 옮겨진 칸 또는 이제 불이 붙으려는 칸으로 이동할 수 없다. 상근이가 있는 칸에 불이 옮겨옴과 동시에 다른 칸으로 이동할 수 있다.

빌딩의 지도가 주어졌을 때, 얼마나 빨리 빌딩을 탈출할 수 있는지 구하는 프로그램을 작성하시오.

입력

첫째 줄에 테스트 케이스의 개수가 주어진다. 테스트 케이스는 최대 100개이다.

각 테스트 케이스의 첫째 줄에는 빌딩 지도의 너비와 높이 w와 h가 주어진다. (1 ≤ w,h ≤ 1000)

다음 h개 줄에는 w개의 문자, 빌딩의 지도가 주어진다.

  • '.': 빈 공간
  • '#': 벽
  • '@': 상근이의 시작 위치
  • '*': 불

각 지도에 @의 개수는 하나이다.

출력

각 테스트 케이스마다 빌딩을 탈출하는데 가장 빠른 시간을 출력한다. 빌딩을 탈출할 수 없는 경우에는 "IMPOSSIBLE"을 출력한다.

예제 입력 1 복사

5
4 3
####
#*@.
####
7 6
###.###
#*#.#*#
#.....#
#.....#
#..@..#
#######
7 4
###.###
#....*#
#@....#
.######
5 5
.....
.***.
.*@*.
.***.
.....
3 3
###
#@#
###

예제 출력 1 복사

2
5
IMPOSSIBLE
IMPOSSIBLE
IMPOSSIBLE

 

 

bfs 문제이다.

불과 상근이가 동시에 움직이는걸 어떻게 코드로 표현해야할지 고민이 되었던 문제이다.

 

문제의 로직

1. 입출력을 모두 받아준다.

2. bfs를 돌린다.

3. startQ와 fireQ를 분리한다.

4. startQ에 첫 시작점을 넣어주고 while문으로 startQ가 empty하지 않을때 돌도록 설정한다.

5. 입력을 받으면서 불의 위치를 저장하고 그 위치를 하나씩 fireQ에 넣어준다.

6. 첫 fireQ의 사이즈만큼 변수에 할당 시키고 그 사이즈만큼 동서남북으로 불을 확장시켜준다.

7. 첫 startQ의 사이즈만큼 변수에 할당 시키고 그 사이즈만큼 동서남북으로 상근이를 움직여준다.

8. 만약에 상근이가 범위를 벗어나면 탈출에 성공했다고 판단하고 return을 해준다.

9. 만약에 상근이가 끝까지 범위를 벗어나지 못하면 탈출을 하지 못했다고 판단하고 impossible을 출력한다.

 

- c++

#include <bits/stdc++.h>
using namespace std;

char graph[1000][1000];
bool visited[1000][1000];
int R, C;
int dir[4][2] = { {0,1},{1,0},{0,-1},{-1,0} };


void bfs(int r, int c, vector<pair<int,int>> fire){

    queue<pair<int,int>> startQ;
    queue<pair<int,int>> fireQ;

    int cnt = 0;

    startQ.push({r,c});

    for(int i = 0 ; i < fire.size(); i++){
        fireQ.push({fire[i].first,fire[i].second});
    }

    while(!startQ.empty()){
        cnt++;
        //fire먼저
        int fqSize = fireQ.size();
        for(int i = 0 ; i < fqSize; i++){
            int cr = fireQ.front().first;
            int cc = fireQ.front().second;
            fireQ.pop();
            for(int j = 0 ; j < 4; j++){
                int nr = cr + dir[j][0];
                int nc = cc + dir[j][1];
                if(nr >= 0 && nc >= 0 && nr < R && nc < C && graph[nr][nc] != '#'){
                    graph[nr][nc] = '#';
                    fireQ.push({nr,nc});
                }
            }
        }

        int sqSize = startQ.size();

        for(int i = 0 ; i < sqSize; i++){
            int cr = startQ.front().first;
            int cc = startQ.front().second;
            startQ.pop();
            for(int j = 0 ; j < 4; j++){
                int nr = cr + dir[j][0];
                int nc = cc + dir[j][1];

                if(nr<0 || nr>=R || nc >=C || nc<0){
                    cout << cnt << "\n";
                    return;
                }
                if(nr >= 0 && nc >= 0 && nr < R && nc < C && graph[nr][nc] != '#' && !visited[nr][nc]){
                    visited[nr][nc]=1;
                    startQ.push({nr,nc});
                }
            }

        }


    }

    cout << "IMPOSSIBLE" << "\n";




}



int main() {

    ios_base::sync_with_stdio(false);
    cout.tie(0);
    cin.tie(0);

    int t;
    cin >> t;

    while(t--){

        cin >> C >> R;
        int r,c;
        vector<pair<int,int>> fire;

        for(int i = 0 ; i < R; i++){
            for(int j = 0 ; j < C; j++){
                cin >> graph[i][j];
                if(graph[i][j] == '*'){
                    fire.push_back({i,j});
                    graph[i][j]='#';
                }else if(graph[i][j]=='@'){
                    r = i;
                    c = j;
                }
            }
        }
        //solve
        bfs(r,c,fire);

        //reset
        memset(graph,' ',sizeof(graph));
        memset(visited,false,sizeof(visited));
    }
    return 0;
}

 

- java

import java.io.*;
import java.sql.Array;
import java.util.*;

class Point{
    int y;
    int x;
    Point(int y, int x){
        this.x = x;
        this.y = y;
    }
}

public class Main {


     static int R,C;
     static boolean [][] visited;
     static final int [][] di = {{0,1},{1,0},{-1,0},{0,-1}};
     static char [][] graph;

    static Queue<Point>startQ;
    static Queue<Point>fireQ;
    static class Point {
        int x;
        int y;

        Point(int y, int x){
            this.y= y;
            this.x = x;
        }
    }



    public static void main(String[] args) throws NumberFormatException, IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer st = new StringTokenizer(br.readLine());

        int T = Integer.parseInt(st.nextToken());

        while (T-- > 0) {

            int r = 0, c = 0;
            st = new StringTokenizer(br.readLine());
            R = Integer.parseInt(st.nextToken());
            C = Integer.parseInt(st.nextToken());

            visited = new boolean[C][R];
            graph = new char[C+1][R+1];
            startQ = new LinkedList<Point>();
            fireQ = new LinkedList<Point>();

            ArrayList<Point> fire = new ArrayList<Point>();

            for (int i = 0; i < C; i++) {
                String s = br.readLine();
                for (int j = 0; j < R; j++) {
                    char ca = s.charAt(j);
                    graph[i][j]=ca;
                    if (ca == '@') {
                        r = j;
                        c = i;
                    } else if (ca == '*') {
                        fire.add(new Point(i, j));
                        graph[i][j]='#';
                    }
                }
            }

            bfs(r, c, fire);
        }
    }

    public static void bfs(int r, int c, ArrayList<Point> fire){


        int cnt = 0;

        startQ.add(new Point(c,r));

        for (int i = 0; i < fire.size() ; i++) {
//            System.out.println(fire.get(i).y + " " + fire.get(i).x + "fire!!!");
            fireQ.add(new Point (fire.get(i).y, fire.get(i).x));
        }

        while(!startQ.isEmpty()){
            int fireQSize = fireQ.size();
            cnt++;

            for(int i = 0 ; i < fireQSize; i++){
                Point poll = fireQ.poll();
                int cr = poll.x;
                int cc = poll.y;
                fireQ.peek();

//                System.out.println(cr+" " +cc);

                for(int j = 0 ; j < 4; j ++){
                    int nr = (cr + di[j][0]);
                    int nc = (cc + di[j][1]);
//                    System.out.println(nr + " " + nc);
                    if(nr >= 0 && nc >= 0 && nr < R && nc < C && (graph[nc][nr]=='.'||graph[nc][nr]=='@')){
//                        System.out.println("fire!!!!");

                        graph[nc][nr] = '#';
                        fireQ.offer(new Point(nc,nr));
                    }
                }
            }




            int startQSize = startQ.size();

            for(int i = 0 ; i < startQSize; i++){
                Point poll = startQ.poll();
                int cr = poll.x;
                int cc = poll.y;
                startQ.peek();

                for(int j = 0 ; j < 4; j ++){
                    int nr = cr + di[j][0];
                    int nc = cc + di[j][1];

                    if(nr<0 || nr>=R || nc >=C || nc<0){
                        System.out.println(cnt);
                        return;
                    }

                    if(nr>=0 && nc >=0 && nr<R && nc < C && graph[nc][nr]!='#'&&!visited[nc][nr]){
                        startQ.offer(new Point(nc,nr));
                        visited[nc][nr]=true;
                    }
                }
            }
        }


        System.out.println("IMPOSSIBLE");

    }



}

'Algorythms' 카테고리의 다른 글

백준 1966번 c++ 풀이  (0) 2023.08.19
백준 1748번 풀이 c++ and java  (0) 2023.07.22
백준 9205번 풀이 c++ and java  (0) 2023.07.20
백준 19941번 풀이 c++ and java  (0) 2023.07.13
백준 2512번 풀이 c++ and java  (0) 2023.07.12