Algorithm

[백준] 빙산 2573번 (c++)

salmon16 2022. 7. 4. 17:41

출처 : 2573번: 빙산 (acmicpc.net)

 

2573번: 빙산

첫 줄에는 이차원 배열의 행의 개수와 열의 개수를 나타내는 두 정수 N과 M이 한 개의 빈칸을 사이에 두고 주어진다. N과 M은 3 이상 300 이하이다. 그 다음 N개의 줄에는 각 줄마다 배열의 각 행을

www.acmicpc.net

풀이 방법

일단 몇 덩어리(변수 cnt) 인지 판단 후 0이면 두 덩어리 이상 안 되는 케이스 이므로 0을 출력한 후 종료

두 덩어리 이상이면 year(기간)을 출력한 후 종료하면 된다.

만약 아직 한 덩어리 라면 빙하를 녹여주는 작업이 필요하다 

빙하는 동시에 녹는데  한 덩어리씩 녹여주는 작업을 한다면 먼저 녹인 빙하가 다른 빙하에 영향을 줄 수 있기 때문에

(ex 빙하가 녹아 0이 되면 이 빙하랑 인접해 있는 아직 처리하지 않은 빙하가 +1만큼 더 녹게 될 수 있다.)

temp라는 배열에 빙하를 복사해서 녹여주어야 한다.

그런 후 몇 덩어리 인지 판단작업을 하며 위 과정을 반복하면 된다.

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

int N, M, year = 0;
int board[301][301], visited[301][301], temp[301][301];
int dx[4] = {0, 0, -1, 1};
int dy[4] = {1, -1, 0, 0};

int melt(int y, int x) {
    int cnt = 0;
    for(int i = 0;i < 4;i++) {
        int nx = x + dx[i];
        int ny = y + dy[i];
        if (nx >= 0 && nx < M && ny >= 0 && ny < N) {
            if (board[ny][nx] == 0) cnt++;
        }
    }
    return cnt;
}

void bfs(int y, int x) {
    queue<pair<int, int>> q;
    q.push(make_pair(y, x));
    visited[y][x] = 1;

    while(!q.empty()) {
        int yy = q.front().first;
        int xx = q.front().second;
        q.pop();
        for (int i = 0;i < 4;i++) {
            int ny = yy + dy[i];
            int nx = xx + dx[i];
            if (ny >= 0 && ny < N && nx >= 0 && nx < M) {
                if (visited[ny][nx] == -1 && board[ny][nx] != 0) {
                    visited[ny][nx] = 1;
                    q.push(make_pair(ny, nx));
                }
            }
        }
    }
}

void solve() {
    while(true) {
        int cnt = 0;
        memset(visited, -1, sizeof(visited));
        memset(temp, 0, sizeof(temp));

        for (int i = 0;i < N;i++) { // 몇 덩어리 인지 판단
            for (int k = 0;k < M;k++) {
                if (board[i][k] != 0 && visited[i][k] == -1) {
                        cnt++;
                        bfs(i, k);
                }
            }
        }
        if (cnt == 0)   {cout << 0; return;} // 두 덩어리 이상 안되고 다 녹는 경우
        if (cnt >= 2)   {cout << year << endl; return;} // 두 덩어리 이상 된 경우
        for (int i = 0;i < N;i++) { // 녹이는 과정
            for (int k = 0;k < M;k++) {
                if (board[i][k] != 0) {
                    temp[i][k] = board[i][k] - melt(i, k);
                    if (temp[i][k] < 0) temp[i][k] = 0; // 음수인 경우
                }
            }
        }
        year++;

        for (int i = 0;i < N;i++) {
            for (int k = 0;k < M;k++) {
                board[i][k] = temp[i][k];
            }
        }
    }
}

int main() {
    memset(board, 0, sizeof(board));
    cin >> N >> M;
    for (int i = 0;i < N;i++) { // ют╥б
        for (int k = 0;k < M;k++) {
            cin >> board[i][k];
        }
    }
    solve();

    return 0;
}

'Algorithm' 카테고리의 다른 글

[백준] 플로이드 11404번 (c++)  (0) 2022.07.11
[백준] 다리 만들기 2146번 (c++)  (0) 2022.07.07
[백준] 숨바꼭질 3 (c++)  (0) 2022.06.16
[프로그래머스] 네트워크 (c++)  (0) 2022.05.24
[백준] 이모티콘 14226번 (c++)  (0) 2022.03.29