Skip to content

Conversation

@kokeunho
Copy link
Collaborator

๐Ÿ”— ๋ฌธ์ œ ๋งํฌ

[BOJ] ๋ถˆ! https://www.acmicpc.net/problem/4179

โœ”๏ธ ์†Œ์š”๋œ ์‹œ๊ฐ„

1h 25min

โœจ ์ˆ˜๋„ ์ฝ”๋“œ

์šฐ์„  ๋ถˆ์ด ๋‚  ์ˆ˜ ์žˆ๋Š” ๊ฐ ์ง€์ ์—์„œ bfs๋ฅผ ์‚ฌ์šฉํ•ด์„œ
๋ถˆ์ด ํผ์งˆ ์ˆ˜ ์žˆ๋Š” ๊ฒฝ๋กœ์˜ ์ง€์ ๋งˆ๋‹ค ๋ช‡ ๋ถ„๋งŒ์— ๋ถˆ์ด ์˜ฎ๊ฒจ๋ถ™์„ ์ˆ˜ ์žˆ๋Š”์ง€ ํ‘œ์‹œํ•ด๋‘์—ˆ์Šต๋‹ˆ๋‹ค.
(๋ถˆ์ด ์—ฌ๋Ÿฌ ์ง€์ ์—์„œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์ ์šฉํ•˜์ง€ ์•Š์•˜๋‹ค๊ฐ€ ์‹œ๊ฐ„์„ ์ข€ ๋ฒ„๋ ธ์Šต๋‹ˆ๋‹ค.)

๊ทธ๋ฆฌ๊ณ  ์ง€ํ›ˆ์ด๋„ bfs๋กœ ํƒˆ์ถœ์„ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค.
์ง€ํ›ˆ์ด๊ฐ€ ๋‹ค์Œ ์ง€์ ์— ์ด๋™ํ•  ๋•Œ, ๊ฑธ๋ฆฐ ์‹œ๊ฐ„๊ณผ ํ•ด๋‹น ์ง€์ ์— ๋ถˆ์ด ์˜ฎ๊ฒจ ๋ถ™์€ ์‹œ๊ฐ„์„ ๋น„๊ตํ•˜์—ฌ
๋ถˆ์ด ์˜ฎ๊ฒจ ๋ถ™๋Š” ์‹œ๊ฐ„๋ณด๋‹ค ๋” ๋น ๋ฅด๋‹ค๋ฉด ํ•ด๋‹น ์ง€์ ์œผ๋กœ ์›€์ง์ž…๋‹ˆ๋‹ค.
๋ฏธ๋กœ๋ฅผ ๋ฒ—์–ด๋‚  ๋•Œ๋งˆ๋‹ค ์‹œ๊ฐ„์„ ์ฒดํฌํ•ด์„œ ํƒˆ์ถœ ์ตœ๋‹จ ์‹œ๊ฐ„์„ ๊ตฌํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ“š ์ƒˆ๋กญ๊ฒŒ ์•Œ๊ฒŒ๋œ ๋‚ด์šฉ

Copy link
Collaborator

@kangrae-jo kangrae-jo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๋ถˆ์ด ๋จผ์ € ํผ์ง€๊ฒŒ ํ•˜๋Š”๊ฒŒ ํ•ต์‹ฌ์ด์—ˆ๋„ค์š”.
์ƒ๊ฐ์ด ์ข€ ์•ˆ๋‚˜์„œ ๊ทผํ˜ธ๋‹˜ ์„ค๋ช… ์‚ด์ง ๋ดค์Šต๋‹ˆ๋‹ค.

๋ฐฉ๋ฒ•์„ ์•„๋‹ˆ๊นŒ ๊ตฌํ˜„์ž์ฒด์˜ ๋‚œ์ด๋„๋Š” ๊ทธ๋ฆฌ๋†’์ง€์•Š์•˜๋˜๊ฒƒ ๊ฐ™์•„์š”.

๊ทผ๋ฐ ์ฒ˜์Œ์— ์ œ์ถœํ–ˆ์„ ๋•Œ ๋ฉ”๋ชจ๋ฆฌ ์ดˆ๊ณผ๊ฐ€ ๋œจ๋”๋ผ๊ตฌ์š”.
๊ทธ๋ž˜์„œ ์ฒ˜์Œ์— ๋ถˆ์˜ ์œ„์น˜๋ฅผ ์ €์žฅํ•˜๋Š” ํ๋Š” ์ „์—ญ์—์„œ ์‚ฌ์ด์ฆˆ๊ฐ€ ๋Š˜์–ด๋‚˜์ง€์•Š๋„๋กํ•˜๊ณ ,
๋ฉ”์„œ๋“œ ๋‚ด๋ถ€์— ๋”ฐ๋กœ ํ๋ฅผ ๋‘์–ด์„œ ๋ณต์‚ฌํ•˜์—ฌ ์‚ฌ์šฉํ–ˆ๋„ค์š”.
(๋ฉ”๋ชจ๋ฆฌ ์ดˆ๊ณผ์— ๋Œ€ํ•œ ์›์ธํŒŒ์•…๊ณผ ๋Œ€์ฒ˜๊ฐ€ ์ ์ ˆํ–ˆ๋Š”์ง€๋Š” ๋ชจ๋ฅด๊ฒ ๋„ค์š”)

๋ญ”๊ฐ€ ์ œ 30๋ฒˆ์จฐ ํ”ผ์•Œ์ธ ์น˜์ฆˆ๋ฌธ์ œ์™€ ๋น„์Šทํ•˜๊ตฐ์š”.

#include <iostream>
#include <queue>
#include <string>
#include <vector>

using namespace std;

const char WALL = '#';
const char PATH = '.';
const char START = 'J';
const char FIRE = 'F';
const int OFFSET[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};

int R, C;
pair<int, int> start;
vector<vector<int>> fireTime;
vector<pair<int, int>> fireInit;

bool isIn(int y, int x) { return 0 <= y && y < R && 0 <= x && x < C; }

void diffuse(vector<string>& board) {
    fireTime.assign(R, vector<int>(C, 1e9));
    
    queue<pair<int, int>> q;
    for (auto [y, x] : fireInit) {
        fireTime[y][x] = 0;
        q.push({y, x});
    }

    while (!q.empty()) {
        auto [y, x] = q.front();
        q.pop();

        for (int dir = 0; dir < 4; dir++) {
            int y_ = y + OFFSET[dir][0];
            int x_ = x + OFFSET[dir][1];
            if (isIn(y_, x_) && board[y_][x_] != WALL && fireTime[y_][x_] > fireTime[y][x] + 1) {
                fireTime[y_][x_] = fireTime[y][x] + 1;
                q.push({y_, x_});
            }
        }
    }
}

int solution(vector<string>& board) {
    vector<vector<bool>> visited(R, vector<bool>(C, false));
    queue<pair<int, int>> q;
    q.push({start.first, start.second});
    visited[start.first][start.second] = true;

    int time = 0;
    while (!q.empty()) {
        int size = q.size();
        time++;
        while (size--) {
            auto [y, x] = q.front();
            q.pop();

            if (y == 0 || y == R - 1 || x == 0 || x == C - 1) return time;

            for (int dir = 0; dir < 4; dir++) {
                int y_ = y + OFFSET[dir][0];
                int x_ = x + OFFSET[dir][1];
                if (isIn(y_, x_) && board[y_][x_] == PATH && fireTime[y_][x_] > time && !visited[y_][x_]) {
                    q.push({y_, x_});
                    visited[y_][x_] = true;
                }
            }
        }
    }
    return -1;
}

int main() {
    cin >> R >> C;

    vector<string> board(R);
    for (int y = 0; y < R; y++) {
        cin >> board[y];
        for (int x = 0; x < C; x++) {
            if (board[y][x] == START) start = {y, x};
            else if (board[y][x] == FIRE) fireInit.push_back({y, x});
        }
    }

    diffuse(board);

    int answer = solution(board);
    if (answer == -1) cout << "IMPOSSIBLE\n";
    else cout << answer << "\n";

    return 0;
}

Comment on lines +73 to +75
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ํ‰ํ–‰์„ธ๊ณ„?์ค‘ ๊ฐ€์žฅ ๋นจ๋ฆฌ ๋‚˜์˜จ ์ง€ํ›ˆ์ด์ž„์ด ๋ณด์žฅ๋จ์œผ๋กœ ๋ฐ”๋กœ current[2] + 1 ๊ฐ’์„ escapeCount๋กœ ๋‘๊ณ  returnํ•ด๋„ ๋ฉ๋‹ˆ๋‹ค.
์šฐ์„ ์ˆœ์œ„ํ๊ฐ€ ์•„๋‹ˆ์–ด๋„ ํ๋Š” ์ˆœ์„œ๋Œ€๋กœ ์Œ“์ด๋‹ˆ๊นŒ์š”

Copy link
Collaborator

@wnsmir wnsmir left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๊ฐ„๋งŒ์— ์‹œ๋ฎฌ๋ ˆ์ด์…˜๋ฌธ์ œ๋ผ ์žฌ๋ฐŒ๊ฒŒ ํ’€๊ณ ์žˆ์—ˆ๋‹ค๋งŒ,,,

ํ•˜

๋ถˆ๋ถ€ํ„ฐ ์›€์ง์ด๋ฉด.. ์ง€ํ›ˆ์ด๊ฐ€ ๊ทธ์ž๋ฆฌ์—์žˆ์œผ๋ฉด ํƒ€์•ผํ•˜๋Š”๊ฑฐ์•„๋‹™๋‹ˆ๊นŒ?!

๊ทธ๋ž˜์„œ ๋‹น์—ฐํžˆ ์ง€ํ›ˆ์ด๋ถ€ํ„ฐ ์›€์ง์ด๊ฒ ๊ฑฐ๋‹ˆ ํ•˜๊ณ  ๋ฐ˜๋ก€ 30๋ถ„๋„˜๊ฒŒ์ฐพ๋‹ค๊ฐ€ ๋ฌธ์ œ ์งˆ๋ฌธ์„ ๋ณด๋‹ˆ
๋ถˆ์€ ์ง€ํ›ˆ์ด๋ฅผ ์‚ผํ‚ค์ง€์•Š์Šต๋‹ˆ๋‹ค!! ๋ผ์žˆ๊ธธ๋ž˜

ํ—ˆํƒˆํ•˜๊ฒŒ ๋ถˆ ์›€์ง์ด๋Š” for๋ฌธ ์ง€ํ›”์ด for๋ฌธ ๋‘๊ฐœ ์ž๋ฆฌ๋ฐ”๊พธ๊ณ  passํ–ˆ์Šต๋‹ˆ๋‹ค..

์ด์‹œ๊ฐ„ ๋นผ๋ฉด ํ•œ 25๋ถ„ ๊ฑธ๋ฆฐ๊ฒƒ๊ฐ™์Šต๋‹ˆ๋‹ค!

from collections import deque

R, C = map(int, input().split())
maze = [list(input().strip()) for _ in range(R)]

fire_q = deque()
jihun_q = deque()
visited = [[False]*C for _ in range(R)]

for i in range(R):
    for j in range(C):
        if maze[i][j] == 'J':
            jihun_q.append((i, j))
            visited[i][j] = True
        elif maze[i][j] == 'F':
            fire_q.append((i, j))

dx = [1, -1, 0, 0]
dy = [0, 0, 1, -1]

time = 0
while jihun_q:
    time += 1

    # ๋ถˆ ํ™•์‚ฐ
    for _ in range(len(fire_q)):
        x, y = fire_q.popleft()
        for d in range(4):
            nx, ny = x+dx[d], y+dy[d]
            if 0 <= nx < R and 0 <= ny < C:
                if maze[nx][ny] == '.' or maze[nx][ny] == 'J':
                    maze[nx][ny] = 'F'
                    fire_q.append((nx, ny))

    # ์ง€ํ›ˆ์ด ์ด๋™
    for _ in range(len(jihun_q)):
        x, y = jihun_q.popleft()
        # ํƒˆ์ถœ ์กฐ๊ฑด: ๊ฐ€์žฅ์ž๋ฆฌ
        if x == 0 or x == R-1 or y == 0 or y == C-1:
            print(time)
            exit()
        for d in range(4):
            nx, ny = x+dx[d], y+dy[d]
            if 0 <= nx < R and 0 <= ny < C:
                if maze[nx][ny] == '.' and not visited[nx][ny]:
                    visited[nx][ny] = True
                    jihun_q.append((nx, ny))

print("IMPOSSIBLE")

Copy link
Member

@9kyo-hwang 9kyo-hwang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ํ•˜ ๋กœ์ง์€ ๋…ผ์Šคํƒ‘์œผ๋กœ ์ซ™์ซ™์ซ™ ์ž‘์„ฑํ–ˆ๋Š”๋ฐ, ์ดˆ๋ฐ˜์— ๋ฐ์ดํ„ฐ ์ž…๋ ฅ๋ฐ›๋Š” ๋ถ€๋ถ„์—์„œ

for(int r = 0; r < R; ++r) {
    string mazeRowStr; 
    cin >> mazeRowStr;

    for(int c = 0; c < C; ++C) {  // ์†Œ๋ฌธ์ž c๋ฅผ ์˜ฌ๋ ค์•ผ ํ•˜๋Š”๋ฐ ๋Œ€๋ฌธ์ž C๋ฅผ ์˜ฌ๋ฆผ!!
        ...
    }
}

์ด ๋‚œ๋ฆฌ๊ฐ€ ๋‚˜์„œ ์ž๊พธ ์‹œ๊ฐ„์ดˆ๊ณผ ํ„ฐ์ ธ์„œ ์ฐพ๋Š” ๋ฐ 30๋ถ„

auto Loop = [&](int& tick) {
    for(tick = 0; ; ++tick) {
        if(tick == 5) {  // ์œ„์— ์ €๊ฑฐ ๋•Œ๋ฌธ์— ์‹œ๊ฐ„์ดˆ๊ณผ ๋‚˜์„œ ๋””๋ฒ„๊น… ์šฉ์œผ๋กœ ๋„ฃ์€ ์กฐ๊ฑด๋ฌธ
            break;
        }
        int moveResult = MoveJihun();
        if(moveResult == 1) {
            return true;
        } else if(moveResult == -1) {
            break;
        } else {
            SpreadFire();
        }
    }
    
    return false;
};

์ € ์กฐ๊ฑด๋ฌธ ์ œ๊ฑฐ ์•ˆํ•ด์„œ ํ‹€๋ ธ์Šต๋‹ˆ๋‹ค ๋– ์„œ ๋˜ 20๋ถ„ ๋‚ ๋ ธ๋„ค์š” ใ…œใ…œใ…œใ…œใ…œใ…œใ…œ

๋ฌธ์ œ ์ž์ฒด๋Š” ๋…๋ฆฝ์ ์œผ๋กœ ์›€์ง์ด๋Š” 2๊ฐœ์˜ ๋ฌผ์ฒด์— ๋Œ€ํ•ด ๋ณ„๋„๋กœ ํ๋ฅผ ๋™์ž‘์‹œํ‚ค๋Š” ๋ฐฉ์‹์ด์ฃ .
์ €๋Š” ํ•˜๋‚˜์˜ ๋ฐ˜๋ณต๋ฌธ ๋‚ด์—์„œ 1. ์ง€ํ›ˆ์ด ์›€์ง์ธ ๋’ค 2. ๋ถˆ์„ ํ™•์‚ฐ์‹œํ‚ค๋Š” ๋ฐฉ์‹์œผ๋กœ ์ง„ํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค.

auto Loop = [&](int& tick) {
    for(tick = 0; ; ++tick) {
        int moveResult = MoveJihun();
        if(moveResult == 1) {
            return true;
        } else if(moveResult == -1) {
            break;
        } else {
            SpreadFire();
        }
    }
    
    return false;
};

int tick;
if(Loop(tick)) {
    cout << tick;
} else {
    cout << "IMPOSSIBLE";
}

๋ฉ”์ธ Loop๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

  • ์ง€ํ›ˆ์ด๋ฅผ ์ด๋™์‹œํ‚ด. 1์ด ๋ฐ˜ํ™˜๋˜๋ฉด ํƒˆ์ถœ ์„ฑ๊ณต, -1์ด๋ผ๋ฉด ์‹คํŒจ, 0์ด๋ผ๋ฉด ์•„์ง ๋ฏธ๋กœ ์•ˆ์„ ์˜๋ฏธ
  • ์ง€ํ›ˆ์ด๊ฐ€ ์•„์ง ๋ฏธ๋กœ ์•ˆ์ด๋ผ๋ฉด ๋ถˆ ํ™•์‚ฐ์„ ์ง„ํ–‰
  • Loop์ด true๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค๋ฉด ๋‚ด๋ถ€์ ์œผ๋กœ ์ง„ํ–‰๋œ loop ํšŸ์ˆ˜๋ฅผ ์ถœ๋ ฅ, ์•„๋‹ˆ๋ผ๋ฉด IMPOSSIBLE ์ถœ๋ ฅ
auto MoveJihun = [&]() -> int {
    if(jihunQ.empty()) {
        return -1;
    }
    
    for(int repeat = jihunQ.size(); repeat > 0; --repeat) {
        const auto [x, y] = jihunQ.front();
        jihunQ.pop();
        
        if(OutOfBound(x, y)) {
            return 1;
        }

        if(maze[x][y] == -2) {
            continue;
        }
        
        for(const auto& [dx, dy] : OFFSET) {
            int nx = x + dx, ny = y + dy;
            if(!OutOfBound(nx, ny) && maze[nx][ny] == -1) {
                maze[nx][ny] = maze[x][y] + 1;
                jihunQ.emplace(nx, ny);
            } else if(OutOfBound(nx, ny)) {
                jihunQ.emplace(nx, ny);
            }
        }
    }
    
    return 0;
};

์ง€ํ›ˆ์ด๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์›€์ง์ž…๋‹ˆ๋‹ค.

  • ์ง€ํ›ˆ์ด Q๊ฐ€ ๋น„์–ด์žˆ๋‹ค๋ฉด, ๋” ์ด์ƒ ๋ฏธ๋กœ ์•ˆ์—์„œ ์ด๋™ํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ -1์„ ๋ฆฌํ„ด
  • ์•„๋‹ˆ๋ผ๋ฉด ์ด๋™์„ ์ˆ˜ํ–‰, ๋งŒ์•ฝ ํ˜„์žฌ ์นธ์ด ๋ฏธ๋กœ ๋ฐ–์ด๋ผ๋ฉด ํƒˆ์ถœ ์„ฑ๊ณต์ด๋ฏ€๋กœ 1 ๋ฆฌํ„ด
  • ๋˜๋Š” ํ˜„์žฌ ์นธ์ด -2๋ผ๋ฉด ๋ถˆ์ด ๋„๋‹ฌํ•œ ์นธ์ด ๋˜์–ด ํ˜„์žฌ ํ™•์ธํ•˜๊ณ  ์žˆ๋Š” ์ƒํƒœ๋Š” ์ œ๊ฑฐ๋˜์–ด์•ผ ํ•  ๋Œ€์ƒ์ด๋ฏ€๋กœ continue
  • ์ง€ํ›ˆ์ด๊ฐ€ ์ด๋™ ๊ฐ€๋Šฅํ•œ ์ƒํƒœ๋ผ๋ฉด "๋ฏธ๋กœ ์•ˆ์ด๋ฉด์„œ ๋นˆ ์นธ์ด๋ฉด ์ด๋™" ๋˜๋Š” "๋ฏธ๋กœ ๋ฐ–์ด๋ผ๋ฉด ์ด๋™"์„ ์ˆ˜ํ–‰
  • ์ด๋ฒˆ ํ ๋ฃจํ”„๋ฅผ ์™„๋ฃŒํ–ˆ๋‹ค๋ฉด ์•„์ง ๋ฏธ๋กœ ์•ˆ์—์„œ ์ƒ์กด ์ค‘์ด๋ฏ€๋กœ 0 ๋ฆฌํ„ด
auto SpreadFire = [&]() -> void {
    for(int repeat = fireQ.size(); repeat > 0; --repeat) {
        const auto [x, y] = fireQ.front();
        fireQ.pop();
        
        for(const auto& [dx, dy] : OFFSET) {
            int nx = x + dx, ny = y + dy;
            if(OutOfBound(nx, ny) || maze[nx][ny] == -2) {
                continue;
            }
            
            maze[nx][ny] = -2;
            fireQ.emplace(nx, ny);
        }
    }
};

๋ถˆ ํ™•์‚ฐ์€ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. ๋ชป ๊ฐ€๋Š” ์นธ๋งŒ ์•„๋‹ˆ๋ผ๋ฉด, ๋ฌด์กฐ๊ฑด ๋‹ค ๋ถˆ ์ง‘์–ด๋„ฃ์œผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์ „์ฒด ์ฝ”๋“œ

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

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    enum {
        WALL = '#',
        EMPTY = '.',
        JIHUN = 'J',
        FIRE = 'F',
    };
    
    int R, C;
    cin >> R >> C;

    queue<pair<int, int>> jihunQ, fireQ;
    vector<vector<int>> maze(R, vector<int>(C));
    
    for(int r = 0; r < R; ++r) {
        string mazeRowStr; 
        cin >> mazeRowStr;

        for(int c = 0; c < C; ++c) {
            switch(mazeRowStr[c]) {
                case WALL:
                    maze[r][c] = -2;
                    break;
                case FIRE:
                    maze[r][c] = -2;
                    fireQ.emplace(r, c);
                    break;
                case EMPTY:
                    maze[r][c] = -1;
                    break;
                case JIHUN:
                    maze[r][c] = 0;
                    jihunQ.emplace(r, c);
                    break;
            }
        }
    }
    
    auto OutOfBound = [R, C](int r, int c) {
        return r < 0 || r >= R || c < 0 || c >= C;
    };
    
    const vector<pair<int, int>> OFFSET{{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
    
    auto MoveJihun = [&]() -> int {
        if(jihunQ.empty()) {
            return -1;
        }
        
        for(int repeat = jihunQ.size(); repeat > 0; --repeat) {
            const auto [x, y] = jihunQ.front();
            jihunQ.pop();
            
            if(OutOfBound(x, y)) {
                return 1;
            }

            if(maze[x][y] == -2) {
                continue;
            }
            
            for(const auto& [dx, dy] : OFFSET) {
                int nx = x + dx, ny = y + dy;
                if(!OutOfBound(nx, ny) && maze[nx][ny] == -1) {
                    maze[nx][ny] = maze[x][y] + 1;
                    jihunQ.emplace(nx, ny);
                } else if(OutOfBound(nx, ny)) {
                    jihunQ.emplace(nx, ny);
                }
            }
        }
        
        return 0;
    };
    
    auto SpreadFire = [&]() -> void {
        for(int repeat = fireQ.size(); repeat > 0; --repeat) {
            const auto [x, y] = fireQ.front();
            fireQ.pop();
            
            for(const auto& [dx, dy] : OFFSET) {
                int nx = x + dx, ny = y + dy;
                if(OutOfBound(nx, ny) || maze[nx][ny] == -2) {
                    continue;
                }
                
                maze[nx][ny] = -2;
                fireQ.emplace(nx, ny);
            }
        }
    };
    
    auto Loop = [&](int& tick) {
        for(tick = 0; ; ++tick) {
            int moveResult = MoveJihun();
            if(moveResult == 1) {
                return true;
            } else if(moveResult == -1) {
                break;
            } else {
                SpreadFire();
            }
        }
        
        return false;
    };
    
    int tick;
    if(Loop(tick)) {
        cout << tick;
    } else {
        cout << "IMPOSSIBLE";
    }

    return 0;
}

Copy link
Collaborator

@g0rnn g0rnn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๋ฌธ์ œ๊ฐ€ ์ข€ ๋ถˆ์นœ์ ˆ ํ•˜๋„ค์š”.. ๋ถˆ์ด ์—ฌ๋Ÿฌ ๊ฐœ์ผ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฐ€์ •๋„ ์—†๊ณ (๋‚ด๊ฐ€ ํ•œ๊ฐœ๋ผ๊ณ  ์ƒ๊ฐํ•œ๊ฒŒ ์ด์ƒํ•œ๊ฑด๊ฐ€), ์นด์šดํŠธ๊ฐ€ 1๋ถ€ํ„ฐ ์‹œ์ž‘ํ•œ๋‹ค๋Š” ์–˜๊ธฐ๋„ ์—†๋„ค์šฉ..

์ €๋Š” while๋ฌธ ๋‚ด์—์„œ fire์˜ ํ์™€ ์ง€ํ›ˆ์ด์˜ ์œ„์น˜๋ฅผ ๋‹ด์€ ํ๋ฅผ ๋™์‹œ์— ๋Œ๋ ธ์Šต๋‹ˆ๋‹ค. ๊ฐ๊ฐ์˜ size๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ while๋ฌธ์„ ๋Œ๋ ค์„œ ์˜ˆ์ƒ์™ธ๋กœ ๊ฒน์น  ์ผ์€ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ง€ํ›ˆ์ด๊ฐ€ ๋จผ์ € ์›€์ง์ธ๋‹ค๋ฉด ๋ถˆ๊ณผ ๋งž๋‹ฅ๋“ค์ผ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋ถˆ์ด ๋จผ์ € ์›€์ง์—ฌ์•ผํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ ์‹œ๊ฐ„์„ ์„ธ๋Š” ์นด์šดํŠธ๊ฐ€ 1๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๊ณ , isEdge๋กœ ๊ฐ€์žฅ์ž๋ฆฌ๋ฅผ ํŒ๋ณ„ํ•˜๋Š” ์ˆœ์„œ๊ฐ€ ๊ผฌ์—ฌ์„œ 10๋ถ„์ •๋„ ์†ํ•ด๋ฅผ ๋ดค๋„ค์š”; ๊ทธ๋ž˜๋„ ๊ณจ๋“œ 3 bfs๋ฌธ์ œ๋Š” ์†์‰ฝ๊ฒŒ ํ’€๋ฆฌ๋Š” ์ง€๊ฒฝ์— ๋„๋‹ฌํ–ˆ๋„ค์š”

๊ณ ์ƒํ•˜์…จ์”๋‹ˆ๋‹ค~~

package beakjoon;

import java.util.*;
import java.io.*;

public class Sol4179 {

    static final char WALL = '#';
    static int r, c, answer=1;
    static char[][] board;
    static int[] J = new int[2];
    static List<int[]> fireStarts = new ArrayList<>();
    static int[][] offset = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        r = Integer.parseInt(st.nextToken());
        c = Integer.parseInt(st.nextToken());
        board = new char[r][c];
        for (int i = 0; i < r; i++) {
            board[i] = br.readLine().toCharArray();
            for (int j = 0; j < c; j++) {
                if (board[i][j] == 'J') {
                    J[0] = j; // x
                    J[1] = i;
                } else if (board[i][j] == 'F') {
                    fireStarts.add(new int[]{j, i});
                }
            }
        }
        br.close();

        if (bfs()) {
            System.out.println(answer);
        } else {
            System.out.println("IMPOSSIBLE");
        }
    }

    private static boolean bfs() {
        Queue<int[]> jihoon = new ArrayDeque<>();
        Queue<int[]> fire = new ArrayDeque<>();
        boolean[][] jVisited = new boolean[r][c];
        boolean[][] fVisited = new boolean[r][c];

        if (isEdge(J[0], J[1])) return true;

        jihoon.offer(new int[]{J[0], J[1]});
        jVisited[J[1]][J[0]] = true;

        // ๋ถˆ ์‹œ์ž‘์œ„์น˜ ์ง€์ •
        for (int[] f : fireStarts) {
            fire.offer(f);
            fVisited[f[1]][f[0]] = true;
        }

        while (!jihoon.isEmpty()) {
            int jSize = jihoon.size();
            int fSize = fire.size();

            while (fSize-- > 0) {
                int x = fire.peek()[0];
                int y = fire.poll()[1];

                for (int[] o : offset) {
                    int nx = x + o[0];
                    int ny = y + o[1];

                    if (nx < 0 || nx >= c || ny < 0 || ny >= r) {
                        continue;
                    }
                    if (fVisited[ny][nx] || board[ny][nx] == WALL) {
                        continue;
                    }
                    fire.offer(new int[]{nx, ny});
                    fVisited[ny][nx] = true;
                    board[ny][nx] = 'F';
                }
            }

            while (jSize-- > 0) {
                int x = jihoon.peek()[0];
                int y = jihoon.poll()[1];

                if (isEdge(x, y)) {
                    return true;
                }

                for (int[] o : offset) {
                    int nx = x + o[0];
                    int ny = y + o[1];

                    if (nx < 0 || nx >= c || ny < 0 || ny >= r) {
                        continue;
                    }
                    if (jVisited[ny][nx] || board[ny][nx] == WALL || board[ny][nx] == 'F') {
                        continue;
                    }

                    jihoon.offer(new int[]{nx, ny});
                    jVisited[ny][nx] = true;
                }
            }
            answer++;
        }
        return false;
    }

    private static boolean isEdge(int x, int y) {
        return x == 0 || y == 0 || x == (c-1) || y == (r-1);
    }
}

@kokeunho kokeunho merged commit 4084daf into main Jul 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants