#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문 처음으로 (계속 녹이기)
}
}
To embed this project on your website, copy the following code and paste it into your website's HTML: