Skip to content

Conversation

@flydongwoo
Copy link
Collaborator

@flydongwoo flydongwoo commented Aug 27, 2025

πŸ”— 문제 링크

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

βœ”οΈ μ†Œμš”λœ μ‹œκ°„

30λΆ„

✨ μˆ˜λ„ μ½”λ“œ

이번 λ¬Έμ œλŠ” μ•žκ³Ό λ’€κ°€ λ‹€λ₯Έ μ‚¬λžŒμ΄ λ§Žμ€ μ–΄μ§€λŸ¬μš΄ ν˜„λŒ€μ‚¬νšŒμ— **'μ•žμœΌλ‘œ 해도, λ’€λ‘œ 해도 같은 ν† λ§ˆν†  같은 μ‚¬λžŒ'**이 되자!
λΌλŠ” 마음으둜 ν† λ§ˆν†  문제 κ°€μ Έμ™”μŠ΅λ‹ˆλ‹€.. λ„€...

μ œκ°€ μƒκ°ν•˜λŠ” 이 ν† λ§ˆν†  문제의 ν¬μΈνŠΈλŠ” ν† λ§ˆν† κ°€ 읡은 μƒνƒœ(1)의 μ’Œν‘œλ₯Ό ν† λ§ˆν†  정보λ₯Ό μž…λ ₯λ°›μ„λ•Œ queue에 μ €μž₯ν•˜λŠ” 것을 μ•„λŠ” 것이라고 μƒκ°ν•©λ‹ˆλ‹€. 즉, queue에 λ‹΄κΈ΄ 읡은 ν† λ§ˆν† (1)λ₯Ό μ‹œμž‘μ μœΌλ‘œ ν•΄μ„œ BFSλ₯Ό λŒλ €μ•Όν•˜μ£ .

μš°μ„ , μ°½κ³  크기 m(μ—΄), n(ν–‰)을 μž…λ ₯λ°›μŠ΅λ‹ˆλ‹€.
n Γ— m 격자λ₯Ό ν•œ μΉΈμ”© 읽어 graph[i][j]에 μ €μž₯ν•˜λŠ”λ°, μ½λŠ” λ™μ•ˆ, 값이 1(읡은 ν† λ§ˆν† ) 인 μΉΈ (i, j)λŠ” 큐 q에 μ¦‰μ‹œ λ„£μŠ΅λ‹ˆλ‹€.
-> μ΄λ ‡κ²Œ ν•˜λ©΄ "닀쀑 μ‹œμž‘μ "이 BFSκ°€ λ©λ‹ˆλ‹€.

이제, BFSλ₯Ό ν•˜λŠ”λ° 큐 μ•žμ—μ„œ μ’Œν‘œ (y, x)λ₯Ό κΊΌλ‚΄λŠ”λ°, 4λ°©ν–₯ 이웃 (ny, nx)에 λŒ€ν•΄, λ²”μœ„ μ•ˆμ΄κ³ , κ·Έ 칸이 0(μ•ˆ 읡음) 이면, graph[ny][nx] = graph[y][x] + 1둜 λ‚ μ§œλ₯Ό 1 늘렀 κΈ°λ‘ν•˜κ³ , 이 μ’Œν‘œ (ny, nx)λ₯Ό 큐에 λ„£μ–΄ λ‹€μŒ μ „νŒŒ λŒ€μƒμœΌλ‘œ λ§Œλ“­λ‹ˆλ‹€.

κ·ΈλŸ¬λ―€λ‘œ, 처음 1μ΄μ—ˆλ˜ 칸듀은 1, ν•˜λ£¨ λ’€ μ „νŒŒλœ 칸은 2, κ·Έ λ‹€μŒμ€ 3 … 처럼 값이 β€œλ‚ μ§œβ€λ‘œ λˆ„μ λ˜λŠ” 것이죠.

κ·Έ λ‹€μŒμœΌλ‘œ, νŒμ •μ„ ν•˜λŠ”λ° 격자λ₯Ό λ‹€μ‹œ μ „λΆ€ μˆœνšŒν•΄μ„œ λ§Œμ•½ 값이 0인 칸이 ν•˜λ‚˜λΌλ„ 남아 있으면 μ΅νžˆμ§€ λͺ»ν•œ ν† λ§ˆν† κ°€ μ‘΄μž¬ν•˜λŠ” κ²ƒμ΄λ―€λ‘œ -1을 좜λ ₯ν•˜κ³  μ’…λ£Œν•©λ‹ˆλ‹€. κ·Έ μ™Έμ—λŠ” λͺ¨λ“  칸의 κ°’ 쀑 μ΅œλŒ“κ°’μ„ result에 μ €μž₯ν•©λ‹ˆλ‹€.

λ§ˆμ§€λ§‰μœΌλ‘œ, 초기 읡은 칸의 값이 1λΆ€ν„° μ‹œμž‘ν•˜λ―€λ‘œ, 총 μ†Œμš” μΌμˆ˜λŠ” resultμ—μ„œ 1을 λΉΌμ€˜μ•Όν•˜μ£ .

예제 3λ²ˆμ„ μ œκ°€ 그림으둜 검증해보면

image

이것은 BFS 탐색이 μ‹œμž‘λ˜λŠ” μ§€μ μž…λ‹ˆλ‹€. μ΄ˆλ‘μƒ‰μ΄ μ‹œμž‘μ μ΄μ£ .

image

이것은 BFS 탐색이 λλ‚˜λŠ” μ§€μ μž…λ‹ˆλ‹€. 주황색이 도착점이죠.

κ·ΈλŸ¬λ―€λ‘œ μ΅œλŒ“κ°’μ΄ 7이 되고 정닡은 7μ—μ„œ 1을 λΊ€ 6이 λ˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

이제 μ½”λ“œ 남기고 이만 μ‚¬λΌμ§€κ² μŠ΅λ‹ˆλ‹€ 쒋은 μ£Όλ§λ˜μ„Έμš” 총총

#include <iostream>
#include <queue>
#include <cstring>

#define MAX_SIZE 1000 + 1

using namespace std;

struct tomato {
    int y, x;
};

queue<tomato> q;

// 우,ν•˜,쒌,상
int dx[4] = { 1, 0, -1, 0 };
int dy[4] = { 0, 1, 0, -1 };

int n, m, result = 0;
int graph[MAX_SIZE][MAX_SIZE];

bool IsInside(int ny, int nx) {
    return (0 <= nx && 0 <= ny && nx < m && ny < n);
}

void bfs(void) {
    while (!q.empty()) {
        int y = q.front().y;
        int x = q.front().x;
        q.pop();

        for (int i = 0; i < 4; i++) {
            int ny = y + dy[i];
            int nx = x + dx[i];

            if (IsInside(ny, nx) == 1 && graph[ny][nx] == 0) {
                graph[ny][nx] = graph[y][x] + 1;
                q.push({ ny, nx });
            }
        }
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> m >> n;

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> graph[i][j];
            if (graph[i][j] == 1) {
                q.push({ i, j });
            }
        }
    }

    bfs();

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (graph[i][j] == 0) {
                cout << -1 << endl;
                return 0;
            }
            if (result < graph[i][j]) {
                result = graph[i][j];
            }
        }
    }

    cout << (result - 1) << endl;
    return 0;
}

πŸ“š μƒˆλ‘­κ²Œ μ•Œκ²Œλœ λ‚΄μš©

queueλŠ” FIFO ꡬ쑰λ₯Ό κ°€μ§€κ³  μžˆμŒμ„ 염두해두고 그림을 κ·Έλ €κ°€λ©° μƒκ°ν•˜λ©΄ μ΄ν•΄ν•˜κΈ° μ‰½λ‹€λŠ” 것을 λŠκΌˆμŠ΅λ‹ˆλ‹€.

Copy link
Collaborator

@Seol-Munhyeok Seol-Munhyeok left a comment

Choose a reason for hiding this comment

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

μƒκ°ν•΄λ³Όκ²Œ λ§Žμ€ BFS λ¬Έμ œλ„€μš”... μ €λŠ” 맀번 1둜 μ±„μ›Œλ‚˜κ°€λ©΄μ„œ 각 BFS의 탐색 λ ˆλ²¨λ§ˆλ‹€ μ§€κΈˆ ν† λ§ˆν† κ°€ λ‹€ μ΅μ—ˆλŠ”μ§€ νŒλ‹¨ν•˜λŠ” λ°©μ‹μœΌλ‘œ ν’€μ—ˆλŠ”λ° Python3λŠ” μ‹œκ°„μ΄ˆκ³Όλ₯Ό λ°›κ³ , PyPy둜 ν•΄μ„œ 톡과λ₯Ό λ°›μ•˜μŠ΅λ‹ˆλ‹€.

μ‹œκ°„μ΄ˆκ³Όμ˜ 원인은 맀번 λͺ¨λ“  배열을 μˆœνšŒν•˜λ©° λͺ¨λ“  ν† λ§ˆν† κ°€ λ‹€ μ΅μ—ˆλŠ”μ§€ μ²΄ν¬ν•˜λŠ” 것을 λ„ˆλ¬΄ 자주 λ°˜λ³΅ν•΄μ„œμ˜€μŠ΅λ‹ˆλ‹€. 효율적인 ν’€μ΄λŠ” λ™μš° λ‹˜μ²˜λŸΌ ν•œλ²ˆμ˜ BFS둜 λͺ¨λ“  배열을 λ‹€ κΈ°λ‘ν•˜κ³ , λ”± ν•œλ²ˆλ§Œ 전체λ₯Ό μˆœνšŒν•΄μ„œ 정닡을 μ°ΎλŠ” κ²ƒμž…λ‹ˆλ‹€.

μ—¬λŸ¬ μ‹œμž‘μ  BFS λ¬Έμ œλΌλŠ” μœ ν˜•μ„ μƒˆλ‘­κ²Œ μ•Œκ²Œλ˜μ—ˆμŠ΅λ‹ˆλ‹€.
BFS λ‹¨κ³„λ§ˆλ‹€ λ ˆλ²¨μ„ 기둝할 λ•Œ, 배열에 이전에 있던 κ°’ + 1을 κΈ°λ‘ν•˜λŠ” λ°©μ‹μœΌλ‘œ μ²˜λ¦¬ν•˜λŠ” 뢀뢄도 κΈ°μ–΅ν•˜κ³  κ°‘λ‹ˆλ‹€.
μˆ˜κ³ ν•˜μ…¨μŠ΅λ‹ˆλ‹€.

[풀이 1] http://boj.kr/29316c1257b94a7fa1635ea9e1df4579
[풀이 2] http://boj.kr/9083d6d8e0324dfba676cec7574cba63

@hyeokbini
Copy link
Collaborator

BFS의 μŠ€ν…Œλ””μ…€λŸ¬ 같은 λ¬Έμ œλ„€μš”. BFSλ₯Ό μ§„ν–‰μ‹œν‚€λ˜, λ‚ μ§œλΌλŠ” κ°œλ…μ΄ μ€‘μš”ν•˜κ²Œ μž‘μš©ν•˜κΈ° λ•Œλ¬Έμ— 큐의 길이λ₯Ό 미리 재 μ€€ λ‹€μŒ, 큐의 길이만큼 전이λ₯Ό μ§„ν–‰ν•˜κ³  λ‚ μ§œλ₯Ό +1ν•΄μ£ΌλŠ” λ‘œμ§μ„ μ‚¬μš©ν–ˆμŠ΅λ‹ˆλ‹€.

맨 λ§ˆμ§€λ§‰μ—λŠ” 전체 배열을 ν•œλ²ˆ ν›‘μ–΄λ³΄λ©΄μ„œ 0이 μžˆλŠ”μ§€ 확인 ν›„, μžˆλ‹€λ©΄ -1을 좜λ ₯ν•΄μ£Όμ—ˆμŠ΅λ‹ˆλ‹€.

제좜 μ½”λ“œμž…λ‹ˆλ‹€. κ³ μƒν•˜μ…¨μ–΄μš”!

ν† λ§ˆν†  / c++
#include <bits/stdc++.h>

using namespace std;

int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
int n, m;
vector<vector<int>> arr;
queue<pair<int, int>> Q;

int main()
{
    //freopen("test.txt", "rt", stdin);
    cin >> m >> n;
    int tmp;
    arr.resize(n, vector<int>(m));
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            cin >> tmp;
            arr[i][j] = tmp;
            if (tmp == 1)
            {
                Q.push({i, j});
            }
        }
    }
    int day = -1;
    while (!Q.empty())
    {
        int qlength = Q.size();
        while (qlength--)
        {
            pair<int, int> cur = Q.front();
            Q.pop();
            for(int i = 0; i < 4; i++)
            {
                int nx = cur.first + dx[i];
                int ny = cur.second + dy[i];
                if(nx < 0 || ny < 0 || nx >= n || ny >= m || arr[nx][ny] != 0)
                {
                    continue;
                }
                arr[nx][ny] = 1;
                Q.push({nx,ny});
            }
        }
        day++;
    }
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            if(arr[i][j] == 0)
            {
                cout << -1;
                return 0;
            }
        }
    }
    cout << day;
}

@mj010504
Copy link
Collaborator

mj010504 commented Sep 8, 2025

μ €λŠ” μ΅ν˜€μ•Ό ν•˜λŠ” ν† λ§ˆν†  총 수λ₯Ό λ―Έλ¦¬κ΅¬ν•˜κ³ , λ‚ μ§œλΌλŠ” κ°œλ…μ΄ μžˆκΈ°μ— μƒˆλ‘œμš΄ 큐λ₯Ό λ§Œλ“€μ–΄ μƒˆλ‘­κ²Œ 읡힌 ν† λ§ˆν† λ₯Ό pushν•˜κ³  탐색이 λλ‚œ ν›„ μƒˆλ‘œμš΄ 큐λ₯Ό μ›λž˜ 큐에 λŒ€μž…ν•˜λŠ” 방식을 μ‚¬μš©ν–ˆμŠ΅λ‹ˆλ‹€. ν˜λΉˆλ‹˜μ²˜λŸΌ 큐의 길이λ₯Ό ν†΅ν•΄μ„œ μ‘°μ ˆν•˜λŠ” 방법도 쒋은 것 κ°™μŠ΅λ‹ˆλ‹€.
μˆ˜κ³ ν•˜μ…¨μŠ΅λ‹ˆλ‹€!

ν† λ§ˆν† 
#include <bits/stdc++.h>

using namespace std;

int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};

int main() {
  //   freopen("input.txt", "rt", stdin);  
    ios::sync_with_stdio(false);  
    cin.tie(0);
    cout.tie(0);
    
    int n, m; cin >> m >> n;
    vector<vector<int>> v(n, vector<int> (m));
    queue<pair<int, int>> q;
    int ripe = 0; // 읡은 ν† λ§ˆν†  수
    int empty = 0;
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < m; j++) {
            int a; cin >> a;
            if(a == 1) {
                ripe++;
                q.push({i, j});
            }

            if(a == -1) empty++;

            v[i][j] = a;
        }
    }

    int total = n * m - empty;

    if(ripe == total) {
        cout << 0;
        return 0;
    }

    int res = 0;
    int sum = 0;

    while(1) {
        queue<pair<int, int>> tq;
        res += 1;
        while(!q.empty()) {
            auto tp = q.front(); q.pop();

            for(int d = 0; d < 4; d++) {
                int xx = tp.first + dx[d];
                int yy = tp.second + dy[d];
                if(xx >= 0 && xx < n && yy >=0 && yy < m && v[xx][yy] == 0) {
                    ripe++;
                    v[xx][yy] = 1;
                    tq.push({xx, yy});
                }
            }
        }
        
        if(ripe == total) break;
        if(tq.empty()) break;
        q = tq;
    }

    if(ripe != total) res = -1;

    cout << res;

    return 0;
}
</details>

@flydongwoo flydongwoo merged commit 6ac834a into main Sep 9, 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.

5 participants