본문 바로가기

algorithm

백준 4179 - 불! (C++)

728x90

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

 

풀이과정

지훈이가 불을 피해서 미로의 가장자리로 이동할 수 있는지 판단하는 문제이다.먼저 불을 전부 확산시키고 지훈이가 이동할 수 있는지 확인할 수 있도록 bfs를 2번 실행시키면 해결할 수 있다. 

! 주의할 점으로, 매번 불을 확산시키고 지훈이가 이동 가능한지 확인하는 것을 반복하면 시간초과가 발생한다.

최대 arr[1000][1000] 배열에서 bfs를 50~100번 정도 실행하면 1초를 넘길 수 있기 때문이다.

풀이

1. 먼저 불을 확산시키며 위치마다 몇분이 걸리는지도 확인한다.

불은 여러곳에 존재할 수 있기 때문에 deque에 전부 넣어놓고 bfs를 실행하여 visited 배열에 걸리는 시간을 저장한다.

void fireMap() {
    // 불 확산
    int y,x,ny,nx;
    while(!fireq.empty()) {
        y = fireq.front().first;
        x = fireq.front().second;
        fireq.pop_front();

        for(int i=0; i<4; i++) {
            ny = y + dy[i];
            nx = x + dx[i];
            if(ny >= R || ny < 0 || nx >= C || nx < 0) continue;
            if(maze[ny][nx] == 1 || visited[ny][nx]) continue;
            visited[ny][nx] = visited[y][x] + 1;
            fireq.push_back({ny,nx});
        }
    }
}

 

2. 지훈이가 매 분 마다 이동하며, 불이 없는 곳 또는 불이 확산된 곳의 시간보다 먼저 도착할 수 있다면 이동해가며 bfs를 실행한다.

int solution() {
    int y,x,depth;
    int ny,nx;
    while(!escapeq.empty()) {
        y = escapeq.front().y;
        x = escapeq.front().x;
        depth = escapeq.front().minute;
        escapeq.pop_front();

        // 끝부분 도착
        if(y == R-1 || y == 0 || x == C-1 || x == 0) {
            return depth;
        }

        for(int i=0; i<4; i++) {
            ny = y + dy[i];
            nx = x + dx[i];
            if(maze[ny][nx] == 1 || moved[ny][nx] == 1) continue;
            // 이동 가능
            if(visited[ny][nx] == 0 || visited[ny][nx] > depth+1) {
                escapeq.push_back({ny,nx,depth+1});
                moved[ny][nx] = 1;
            }
        }
    }
    return -1;
}

 

! 지훈이가 이미 탈출한 상태일 수 있기 때문에 입력할 때 미리 체크해놓아야 한다.

 

코드

#include <iostream>
#include <stdio.h>
#include <memory.h>
#include <deque>
using namespace std;

int R,C;
int maze[1000][1000];
int visited[1000][1000];
int moved[1000][1000];
int dy[4] = {-1,1,0,0};
int dx[4] = {0,0,-1,1};
deque < pair < int,int > > fireq;
typedef struct option {
    int y,x,minute;
}op;
deque < op > escapeq;

void fireMap() {
    // 불 확산
    int y,x,ny,nx;
    while(!fireq.empty()) {
        y = fireq.front().first;
        x = fireq.front().second;
        fireq.pop_front();

        for(int i=0; i<4; i++) {
            ny = y + dy[i];
            nx = x + dx[i];
            if(ny >= R || ny < 0 || nx >= C || nx < 0) continue;
            if(maze[ny][nx] == 1 || visited[ny][nx]) continue;
            visited[ny][nx] = visited[y][x] + 1;
            fireq.push_back({ny,nx});
        }
    }
}

int solution() {
    int y,x,depth;
    int ny,nx;
    while(!escapeq.empty()) {
        y = escapeq.front().y;
        x = escapeq.front().x;
        depth = escapeq.front().minute;
        escapeq.pop_front();

        // 끝부분 도착
        if(y == R-1 || y == 0 || x == C-1 || x == 0) {
            return depth;
        }

        for(int i=0; i<4; i++) {
            ny = y + dy[i];
            nx = x + dx[i];
            if(maze[ny][nx] == 1 || moved[ny][nx] == 1) continue;
            // 이동 가능
            if(visited[ny][nx] == 0 || visited[ny][nx] > depth+1) {
                escapeq.push_back({ny,nx,depth+1});
                moved[ny][nx] = 1;
            }
        }
    }
    return -1;
}

int main() {
    int result = -1;
    string s;
    scanf("%d %d",&R,&C);
    for(int i=0; i<R; i++) {
        cin >> s;
        for(int j=0; j<C; j++) {
            if(s[j] == '#') maze[i][j] = 1;
            else if(s[j] == 'F') {
                fireq.push_back({i,j});
                visited[i][j] = 1;
            }
            else if(s[j] == 'J') {
                // 이미 탈출해있을 경우
                if(i == R-1 || i == 0 || j == C-1 || j == 0) {
                    result = 0;
                }
                escapeq.push_back({i,j,1});
                moved[i][j] = 1;
            }
        }
    }
    if(result == 0) {
        printf("1\n");
        return 0;
    }
    fireMap();
    result = solution();
    (result == -1) ? printf("IMPOSSIBLE\n") : printf("%d\n",result);
}
728x90

'algorithm' 카테고리의 다른 글

백준 17825 - 주사위 윷놀이  (1) 2024.12.30
백준 17141 - 연구소 2  (0) 2024.12.10
백준 13549 - 숨바꼭질 3  (0) 2024.11.03
백준 7569 - 토마토  (0) 2024.10.20
백준 11660 - 구간 합 구하기 5  (0) 2024.10.06