굉장히 비슷한 문제가 많습니다. (2468번 안전 영역 등) 다들 naive하게 풀리는 문제들입니다.
두 가지 함수를 구현해야 합니다.
- 1년 후 빙산의 상태를 계산하는 함수
- 빙산의 개수를 세는 함수: DFS 또는 BFS 사용
이걸 써서 빙산 개수가 하나가 아니게 될 때까지 매년마다 빙산 개수를 세면 됩니다. 만약 빙산 개수가 0이 되면 다 녹을 때까지 분리가 안 되는 거니까 0을 출력하고, 2개 이상이 되면 그 때 연도를 출력합니다.
#include<cstdio>
using namespace std;
int n, m;
int Height[300][300];
bool IsIce[300][300];
int Adj[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
void dfs(int i, int j) {
if (IsIce[i][j]) {
IsIce[i][j] = false;
for (int k = 0; k < 4; k++)
dfs(i + Adj[k][0], j + Adj[k][1]);
}
}
int num_iceberg(void) {
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
IsIce[i][j] = Height[i][j] > 0? true : false;
int cnt = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
if (IsIce[i][j]) {
cnt++;
dfs(i, j);
}
return cnt;
}
void melt(void) {
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
if (Height[i][j] > 0)
for (int k = 0; k < 4; k++)
if (Height[i][j] > 0 && Height[i + Adj[k][0]][j + Adj[k][1]] == -1)
Height[i][j]--;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
if (Height[i][j] == 0)
Height[i][j] = -1;
}
int main(void) {
scanf("%d %d", &n, &m);
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++) {
scanf("%d", &Height[i][j]);
if (Height[i][j] == 0)
Height[i][j] = -1;
}
int y = 0, ni;
while ((ni = num_iceberg()) == 1) {
melt();
y++;
}
printf("%d", ni > 1? y : 0);
return 0;
}