[BOJ] 2638๋ฒˆ | ์น˜์ฆˆ (C++)

2024. 2. 1. 17:54ใ†Coding Test/BOJ

๐Ÿ”—๋ฌธ์ œ ๋ณด๋Ÿฌ๊ฐ€๊ธฐ
 

2638๋ฒˆ: ์น˜์ฆˆ

์ฒซ์งธ ์ค„์—๋Š” ๋ชจ๋ˆˆ์ข…์ด์˜ ํฌ๊ธฐ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋‘ ๊ฐœ์˜ ์ •์ˆ˜ N, M (5 ≤ N, M ≤ 100)์ด ์ฃผ์–ด์ง„๋‹ค. ๊ทธ ๋‹ค์Œ N๊ฐœ์˜ ์ค„์—๋Š” ๋ชจ๋ˆˆ์ข…์ด ์œ„์˜ ๊ฒฉ์ž์— ์น˜์ฆˆ๊ฐ€ ์žˆ๋Š” ๋ถ€๋ถ„์€ 1๋กœ ํ‘œ์‹œ๋˜๊ณ , ์น˜์ฆˆ๊ฐ€ ์—†๋Š” ๋ถ€๋ถ„์€ 0์œผ๋กœ

www.acmicpc.net

 

๐Ÿ‘จ‍๐Ÿ’ปํ’€์ด ๊ณผ์ •

 

๋‚ด๋ถ€ ๊ณต๊ธฐ์™€ ์™ธ๋ถ€ ๊ณต๊ธฐ๋ฅผ ์–ด๋–ป๊ฒŒ ๊ตฌ๋ณ„ํ• ๊นŒ ๊ณ ๋ฏผํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ฌธ๋“ ๋– ์˜ค๋ฅธ ์ƒ๊ฐ์€ ๋‹ค๊ฐํ˜• ์™ธ๋ถ€ ๋‚ด๋ถ€ ํŒ๋ณ„ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด์—ˆ๋Š”๋ฐ, ์น˜์ฆˆ๊ฐ€ ๋‹ค๊ฐํ˜•์ด ์•„๋‹ ์ˆ˜๋„ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ ์šฉํ•  ์ˆ˜๊ฐ€ ์—†๋”๋ผ๊ตฌ์š”.

 

๊ทธ๋ž˜์„œ ๋ฌธ์ œ์—์„œ ์ฃผ์–ด์ง„ ์ •๋ณด์ธ, "๊ฐ€์žฅ์ž๋ฆฌ์—๋Š” ์น˜์ฆˆ๊ฐ€ ๋†“์ด์ง€ ์•Š๋Š”๋‹ค"๋ผ๋Š” ๊ฑธ ํ™œ์šฉํ•ด ๊ฐ€์žฅ์ž๋ฆฌ์—์„œ๋ถ€ํ„ฐ BFS๋ฅผ ํ†ตํ•ด ์™ธ๋ถ€ ๊ณต๊ธฐ๋ฅผ ๋งŒ๋“ค์–ด์ฃผ๊ธฐ๋กœ ๊ฒฐ์ •ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์ด ๋กœ์ง์„ ์œ„ํ•ด, ์ž…๋ ฅ ์„ธํŒ…์„ ํ•  ๋•Œ ์กฐ๊ธˆ ๋‹ค๋ฅด๊ฒŒ ์„ธํŒ…ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

// ์ „์—ญ ๋ณ€์ˆ˜๋“ค
#define EXTERNAL_AIR -1
#define AIR -2
#define REMOVE_TARGET_CHEESE -3

using Point = pair<int, int>;
int MaxRow, MaxCol;
vector<vector<int>> Directions{ {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
void Initialize(vector<vector<int>>& field)
{
    for (int row = 0; row < MaxRow; row++)
    {
        for (int col = 0; col < MaxCol; col++)
        {
            cin >> field[row][col];

            if (field[row][col] == 0)       field[row][col] = AIR;
            else if (field[row][col] == 1)  field[row][col] = 0;        // ์น˜์ฆˆ๊ฐ€ ์™ธ๋ถ€ ๊ณต๊ธฐ์™€ ์ ‘์ด‰ํ•˜๋Š” ์นธ ์ˆ˜ (์šฐ์„  ์ดˆ๊นƒ๊ฐ’์€ ๋ชจ๋‘ 0์œผ๋กœ)
        }
    }
}

 

๊ธฐ์กด ์ž…๋ ฅ์—์„œ ๊ณต๊ธฐ์˜€๋˜ ์นธ(0)์„ AIR(-2)๋กœ, ์น˜์ฆˆ์˜€๋˜ ์นธ(1)์„ 0์œผ๋กœ ์„ธํŒ…ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์น˜์ฆˆ๊ฐ€ ์žˆ๋Š” ์นธ์˜ ์ •๋ณด๋ฅผ ์™ธ๋ถ€ ๊ณต๊ธฐ๊ฐ€ ์ ‘์ด‰ํ•˜๋Š” ๋ณ€์˜ ์ˆ˜๋กœ ์„ค์ •ํ•ด์ฃผ๊ธฐ ์œ„ํ•จ์ž…๋‹ˆ๋‹ค. ๋‚ด๋ถ€ ๊นŠ์ˆ™ํžˆ ์žˆ๋Š” ์น˜์ฆˆ์˜ ๊ฒฝ์šฐ์—๋Š” ์™ธ๋ถ€ ๊ณต๊ธฐ์™€ ์ ‘์ด‰ํ•˜์ง€ ์•Š์•„ 0์ด๋ž€ ๊ฐ’์„ ๊ฐ–๊ธฐ ๋•Œ๋ฌธ์—, ๊ณต๊ธฐ์™€ ์ด๋ฅผ ๊ตฌ๋ณ„ํ•ด์ฃผ๊ธฐ ์œ„ํ•ด ๋‹ค๋ฅด๊ฒŒ ์„ธํŒ…ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

 

 

๊ทธ ํ›„, ๊ฐ€์žฅ์ž๋ฆฌ์—๋Š” ์น˜์ฆˆ๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— (0, 0) ์œ„์น˜์—์„œ๋ถ€ํ„ฐ BFS ๋ฐฉ์‹์„ ํ†ตํ•ด ์™ธ๋ถ€ ๊ณต๊ธฐ๋ฅผ ์„ธํŒ…ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ ๊ณผ์ •์—์„œ ์น˜์ฆˆ๋ฅผ ๋งŒ๋‚˜๊ฒŒ ๋˜๋ฉด, ํ•ด๋‹น ์น˜์ฆˆ์˜ ๊ฐ’์„ 1 ์ฆ๊ฐ€์‹œ์ผœ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

๋งŒ์•ฝ ํ•ด๋‹น ์น˜์ฆˆ์˜ ๊ฐ’์ด 2 ์ด์ƒ์ด๋ผ๋ฉด, ์ œ๊ฑฐํ•  ๋Œ€์ƒ์œผ๋กœ ๊ฐ„์ฃผํ•˜๊ณ  ๋ณ„๋„์˜ ํ(Queue)์— ๋‹ด์•„์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

void FillExternalAirAndFindRemovingCheeses(vector<vector<int>>& field, queue<Point>& removeTargetCheeses, int startRow, int startCol)
{
    queue<Point> positions;
    field[startRow][startCol] = EXTERNAL_AIR;
    positions.emplace(Point(startRow, startCol));

    while (!positions.empty())
    {
        int row = positions.front().first;
        int col = positions.front().second;
        positions.pop();

        for (const vector<int>& direction : Directions)
        {
            int nextRow = row + direction[0];
            int nextCol = col + direction[1];

            if (nextRow < 0 or nextRow >= MaxRow or nextCol < 0 or nextCol >= MaxCol)
                continue;

            if (field[nextRow][nextCol] == EXTERNAL_AIR or field[nextRow][nextCol] == REMOVE_TARGET_CHEESE)
                continue;
            
            if (field[nextRow][nextCol] >= 0)   // ์น˜์ฆˆ์ผ ๊ฒฝ์šฐ, ์™ธ๋ถ€ ์ ‘์ด‰ ๊ณต๊ธฐ ๊ฐœ์ˆ˜๋ฅผ ๋Š˜๋ ค์ฃผ๊ธฐ
            {
                field[nextRow][nextCol]++;

                if (field[nextRow][nextCol] >= 2)
                {
                    field[nextRow][nextCol] = REMOVE_TARGET_CHEESE;
                    removeTargetCheeses.emplace(Point(nextRow, nextCol));
                }
                continue;
            }

            field[nextRow][nextCol] = EXTERNAL_AIR;
            positions.emplace(Point(nextRow, nextCol));
        }
    }
}

 

์ด๋ ‡๊ฒŒ ์™ธ๋ถ€ ๊ณต๊ธฐ๋ฅผ ์ฑ„์šฐ๊ณ  ์ œ๊ฑฐํ•  ์น˜์ฆˆ๋“ค์„ ์ฐพ์•˜๋‹ค๋ฉด, ์น˜์ฆˆ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ์ œ๊ฑฐํ•œ ์ž๋ฆฌ์—์„œ ๋‹ค์‹œ ์™ธ๋ถ€ ๊ณต๊ธฐ๋ฅผ ํผํŠธ๋ฆฌ๊ณ , ๊ทธ ๊ณผ์ •์—์„œ ๋˜ ์ œ๊ฑฐํ•  ์น˜์ฆˆ๋ฅผ ์ฐพ๊ณ ... ์ด ๊ณผ์ •์„ ๋” ์ด์ƒ ์ œ๊ฑฐํ•  ์น˜์ฆˆ๊ฐ€ ์—†์„ ๋•Œ๊นŒ์ง€ ๋ฐ˜๋ณตํ•ด์ค๋‹ˆ๋‹ค.

void Update(vector<vector<int>>& field, queue<Point>& removeTargetCheeses)
{
    int size = removeTargetCheeses.size();

    for (int i = 0; i < size; i++)
    {
        Point cheesePosition = removeTargetCheeses.front();
        int row = cheesePosition.first;
        int col = cheesePosition.second;

        removeTargetCheeses.pop();
        FillExternalAirAndFindRemovingCheeses(field, removeTargetCheeses, row, col);
    }
}

 

์œ„์˜ ํ•จ์ˆ˜๋“ค์„ main() ํ•จ์ˆ˜์—์„œ ์ž˜ ๋™์ž‘ํ•˜๋„๋ก ์‹คํ–‰ํ•ด์ฃผ๋ฉด ๋์ž…๋‹ˆ๋‹ค.

int main()
{
    FAST_IO
    cin >> MaxRow >> MaxCol;

    // 1. ์ž…๋ ฅ ๋ฐ›๊ณ  ์„ธํŒ…
    vector<vector<int>> field(MaxRow, vector<int>(MaxCol));
    Initialize(field);

    // 2. ์™ธ๋ถ€ ๊ณต๊ธฐ๋ฅผ ์ฑ„์šฐ๊ณ , ๊ทธ ๊ณผ์ •์—์„œ ์ œ๊ฑฐํ•  ์น˜์ฆˆ๋“ค ์ฐพ๊ธฐ
    queue<Point> removeTargetCheeses;
    FillExternalAirAndFindRemovingCheeses(field, removeTargetCheeses, 0, 0);   // ๊ฐ€์žฅ์ž๋ฆฌ์—๋Š” ์น˜์ฆˆ๊ฐ€ ์—†๋‹ค๊ณ  ํ–ˆ์œผ๋ฏ€๋กœ (0, 0)๋ถ€ํ„ฐ ์‹œ์ž‘

    // 3. ๋” ์ด์ƒ ์ œ๊ฑฐํ•  ์น˜์ฆˆ๊ฐ€ ์—†์„ ๋•Œ๊นŒ์ง€ ๋ฐ˜๋ณต
    int time = 0;
    while (!removeTargetCheeses.empty())
    {
        Update(field, removeTargetCheeses);
        time++;
    }

    cout << time;
    return 0;
}

 

 

 

โœ๏ธ์†Œ์Šค ์ฝ”๋“œ ๋ฐ ๊ฒฐ๊ณผ

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

using namespace std;
using Point = pair<int, int>;

#define FAST_IO ios::sync_with_stdio(false); cout.tie(NULL); cin.tie(NULL);
#define EXTERNAL_AIR -1
#define AIR -2
#define REMOVE_TARGET_CHEESE -3


int MaxRow, MaxCol;
vector<vector<int>> Directions{ {-1, 0}, {1, 0}, {0, -1}, {0, 1} };

void FillExternalAirAndFindRemovingCheeses(vector<vector<int>>& field, queue<Point>& removeTargetCheeses, int startRow, int startCol)
{
    queue<Point> positions;
    field[startRow][startCol] = EXTERNAL_AIR;
    positions.emplace(Point(startRow, startCol));

    while (!positions.empty())
    {
        int row = positions.front().first;
        int col = positions.front().second;
        positions.pop();

        for (const vector<int>& direction : Directions)
        {
            int nextRow = row + direction[0];
            int nextCol = col + direction[1];

            if (nextRow < 0 or nextRow >= MaxRow or nextCol < 0 or nextCol >= MaxCol)
                continue;

            if (field[nextRow][nextCol] == EXTERNAL_AIR or field[nextRow][nextCol] == REMOVE_TARGET_CHEESE)
                continue;
            
            if (field[nextRow][nextCol] >= 0)   // ์น˜์ฆˆ์ผ ๊ฒฝ์šฐ, ์™ธ๋ถ€ ์ ‘์ด‰ ๊ณต๊ธฐ ๊ฐœ์ˆ˜๋ฅผ ๋Š˜๋ ค์ฃผ๊ธฐ
            {
                field[nextRow][nextCol]++;

                if (field[nextRow][nextCol] >= 2)
                {
                    field[nextRow][nextCol] = REMOVE_TARGET_CHEESE;
                    removeTargetCheeses.emplace(Point(nextRow, nextCol));
                }
                continue;
            }

            field[nextRow][nextCol] = EXTERNAL_AIR;
            positions.emplace(Point(nextRow, nextCol));
        }
    }
}

void Update(vector<vector<int>>& field, queue<Point>& removeTargetCheeses)
{
    int size = removeTargetCheeses.size();

    for (int i = 0; i < size; i++)
    {
        Point cheesePosition = removeTargetCheeses.front();
        int row = cheesePosition.first;
        int col = cheesePosition.second;

        removeTargetCheeses.pop();
        FillExternalAirAndFindRemovingCheeses(field, removeTargetCheeses, row, col);
    }
}

void Initialize(vector<vector<int>>& field)
{
    for (int row = 0; row < MaxRow; row++)
    {
        for (int col = 0; col < MaxCol; col++)
        {
            cin >> field[row][col];

            if (field[row][col] == 0)       field[row][col] = AIR;
            else if (field[row][col] == 1)  field[row][col] = 0;        // ์น˜์ฆˆ๊ฐ€ ์™ธ๋ถ€ ๊ณต๊ธฐ์™€ ์ ‘์ด‰ํ•˜๋Š” ์นธ ์ˆ˜ (์šฐ์„  ์ดˆ๊นƒ๊ฐ’์€ ๋ชจ๋‘ 0์œผ๋กœ)
        }
    }
}

int main()
{
    FAST_IO
    cin >> MaxRow >> MaxCol;

    // 1. ์ž…๋ ฅ ๋ฐ›๊ณ  ์„ธํŒ…
    vector<vector<int>> field(MaxRow, vector<int>(MaxCol));
    Initialize(field);

    // 2. ์™ธ๋ถ€ ๊ณต๊ธฐ๋ฅผ ์ฑ„์šฐ๊ณ , ๊ทธ ๊ณผ์ •์—์„œ ์ œ๊ฑฐํ•  ์น˜์ฆˆ๋“ค ์ฐพ๊ธฐ
    queue<Point> removeTargetCheeses;
    FillExternalAirAndFindRemovingCheeses(field, removeTargetCheeses, 0, 0);   // ๊ฐ€์žฅ์ž๋ฆฌ์—๋Š” ์น˜์ฆˆ๊ฐ€ ์—†๋‹ค๊ณ  ํ–ˆ์œผ๋ฏ€๋กœ (0, 0)๋ถ€ํ„ฐ ์‹œ์ž‘

    // 3. ๋” ์ด์ƒ ์ œ๊ฑฐํ•  ์น˜์ฆˆ๊ฐ€ ์—†์„ ๋•Œ๊นŒ์ง€ ๋ฐ˜๋ณต
    int time = 0;
    while (!removeTargetCheeses.empty())
    {
        Update(field, removeTargetCheeses);
        time++;
    }

    cout << time;
    return 0;
}

 

 

 

728x90
๋ฐ˜์‘ํ˜•