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

#define X first
#define Y second

int n, m, year=0;
int area[303][303];
int vis[303][303];
int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};

bool check(int i, int j) { 
    //범위 밖
    if(i<0 || i>=n || j<0 || j>=m) return 1;
    else return 0;
}

// 녹이기, 주변 0 개수 찾아서 빼기
void melting() {
    int zero[303][303] = {0}; // 녹을 양 저장
    
    //모든 칸을 돌며 주변 바다(0) 개수 카운트
    for(int i=0; i<n; i++) {
        for(int j=0; j<m; j++) {
            if(area[i][j] == 0) continue;
            // 상하좌우 보면서 area[nx][ny] == 0이면 zero[i][j]++
            for(int idx=0; idx<4; idx++) {
                int nx=i+dx[idx];
                int ny=j+dy[idx];
                if(check(nx,ny)) continue;
                if(area[nx][ny]==0) zero[i][j]++;
            }
        }
    }
    
    //카운트된 양만큼 한꺼번에 빼주기
    for(int i=0; i<n; i++) {
        for(int j=0; j<m; j++)
            area[i][j] = max(0, area[i][j] - zero[i][j]);
    }
}

// 상태 확인
int status() {
    // (A) 현재 남아있는 전체 빙산 칸(cnt1) 세기
    // (B) 그중 아무 칸 하나(x, y) 골라서 BFS 시작
    // (C) BFS로 연결된 칸(cnt2) 세기
    int cnt1=0,x=-1,y=-1;
    for(int i=0; i<n; i++) {
        for(int j=0; j<m;j++) {
            if(area[i][j]){
                x=i;
                y=j;
                cnt1++;
            }
        }
    }
    if(cnt1 == 0) return 0;  // 다 녹음
    int cnt2=0;
    queue<pair<int,int>> q;
    q.push({x,y});
    vis[x][y]=1;
    while(!q.empty()){
        auto cur=q.front();q.pop();
        cnt2++;
        for(int idx=0; idx<4; idx++) {
            int nx=cur.X+dx[idx];
            int ny=cur.Y+dy[idx];
            //범위 밖, 빙산 없음, 방문 됨
            if(check(nx,ny)) continue;
            if(area[nx][ny]<=0 || vis[nx][ny]==1) continue;
            vis[nx][ny]=1;
            q.push({nx,ny});
        }
    }
    if(cnt1 == cnt2) return 1;    // 아직 한 덩어리
    return 2;                     // 개수가 다르면 분리됨
}


int main() {
    cin>>n>>m;
    for(int i=0; i<n; i++) { 
        for(int j=0; j<m; j++) {
            cin >> area[i][j];
        }
    }

    while(true) {
        year++;         // 1년 지나고
        melting();      // 녹이고
        
        memset(vis, 0, sizeof(vis)); // 방문 배열 닦아주고
        int res = status();          // 상태 확인
        
        if(res == 0) { cout << 0; return 0; }    // 두 덩어리 되기 전에 다 녹음
        if(res == 2) { cout << year; return 0; } // 드디어 두 덩어리!
        // res == 1이면 다시 while문 처음으로 (계속 녹이기)
    }
}

Embed on website

To embed this project on your website, copy the following code and paste it into your website's HTML: