Skip to content

Commit 6f0533e

Browse files
committed
[Gold IV] Title: 빙산, Time: 104 ms, Memory: 3080 KB -BaekjoonHub
1 parent 5a58313 commit 6f0533e

2 files changed

Lines changed: 309 additions & 0 deletions

File tree

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
# [Gold IV] 빙산 - 2573
2+
3+
[문제 링크](https://www.acmicpc.net/problem/2573)
4+
5+
### 성능 요약
6+
7+
메모리: 3080 KB, 시간: 104 ms
8+
9+
### 분류
10+
11+
구현, 그래프 이론, 그래프 탐색, 너비 우선 탐색, 깊이 우선 탐색
12+
13+
### 제출 일자
14+
15+
2025년 10월 19일 15:30:14
16+
17+
### 문제 설명
18+
19+
<p>지구 온난화로 인하여 북극의 빙산이 녹고 있다. 빙산을 그림 1과 같이 2차원 배열에 표시한다고 하자. 빙산의 각 부분별 높이 정보는 배열의 각 칸에 양의 정수로 저장된다. 빙산 이외의 바다에 해당되는 칸에는 0이 저장된다. 그림 1에서 빈칸은 모두 0으로 채워져 있다고 생각한다.</p>
20+
21+
<table class="table table-bordered td-center table-center-35 td-width-5">
22+
<tbody>
23+
<tr>
24+
<td> </td>
25+
<td> </td>
26+
<td> </td>
27+
<td> </td>
28+
<td> </td>
29+
<td> </td>
30+
<td> </td>
31+
</tr>
32+
<tr>
33+
<td> </td>
34+
<td>2</td>
35+
<td>4</td>
36+
<td>5</td>
37+
<td>3</td>
38+
<td> </td>
39+
<td> </td>
40+
</tr>
41+
<tr>
42+
<td> </td>
43+
<td>3</td>
44+
<td> </td>
45+
<td>2</td>
46+
<td>5</td>
47+
<td>2</td>
48+
<td> </td>
49+
</tr>
50+
<tr>
51+
<td> </td>
52+
<td>7</td>
53+
<td>6</td>
54+
<td>2</td>
55+
<td>4</td>
56+
<td> </td>
57+
<td> </td>
58+
</tr>
59+
<tr>
60+
<td> </td>
61+
<td> </td>
62+
<td> </td>
63+
<td> </td>
64+
<td> </td>
65+
<td> </td>
66+
<td> </td>
67+
</tr>
68+
</tbody>
69+
</table>
70+
71+
<p style="text-align: center;">그림 1. 행의 개수가 5이고 열의 개수가 7인 2차원 배열에 저장된 빙산의 높이 정보</p>
72+
73+
<p><span style="line-height:1.6em">빙산의 높이는 바닷물에 많이 접해있는 부분에서 더 빨리 줄어들기 때문에, 배열에서 빙산의 각 부분에 해당되는 칸에 있는 높이는 일년마다 그 칸에 동서남북 네 방향으로 붙어있는 0이 저장된 칸의 개수만큼 줄어든다. 단, 각 칸에 저장된 높이는 0보다 더 줄어들지 않는다. 바닷물은 호수처럼 빙산에 둘러싸여 있을 수도 있다. 따라서 그림 1의 빙산은 일년후에 그림 2와 같이 변형된다.</span></p>
74+
75+
<p>그림 3은 그림 1의 빙산이 2년 후에 변한 모습을 보여준다. 2차원 배열에서 동서남북 방향으로 붙어있는 칸들은 서로 연결되어 있다고 말한다. 따라서 그림 2의 빙산은 한 덩어리이지만, 그림 3의 빙산은 세 덩어리로 분리되어 있다.</p>
76+
77+
<table class="table table-bordered td-center table-center-35 td-width-5">
78+
<tbody>
79+
<tr>
80+
<td> </td>
81+
<td> </td>
82+
<td> </td>
83+
<td> </td>
84+
<td> </td>
85+
<td> </td>
86+
<td> </td>
87+
</tr>
88+
<tr>
89+
<td> </td>
90+
<td> </td>
91+
<td>2</td>
92+
<td>4</td>
93+
<td>1</td>
94+
<td> </td>
95+
<td> </td>
96+
</tr>
97+
<tr>
98+
<td> </td>
99+
<td>1</td>
100+
<td> </td>
101+
<td>1</td>
102+
<td>5</td>
103+
<td> </td>
104+
<td> </td>
105+
</tr>
106+
<tr>
107+
<td> </td>
108+
<td>5</td>
109+
<td>4</td>
110+
<td>1</td>
111+
<td>2</td>
112+
<td> </td>
113+
<td> </td>
114+
</tr>
115+
<tr>
116+
<td> </td>
117+
<td> </td>
118+
<td> </td>
119+
<td> </td>
120+
<td> </td>
121+
<td> </td>
122+
<td> </td>
123+
</tr>
124+
</tbody>
125+
</table>
126+
127+
<p style="text-align: center;">그림 2</p>
128+
129+
<table class="table table-bordered td-center table-center-35 td-width-5">
130+
<tbody>
131+
<tr>
132+
<td> </td>
133+
<td> </td>
134+
<td> </td>
135+
<td> </td>
136+
<td> </td>
137+
<td> </td>
138+
<td> </td>
139+
</tr>
140+
<tr>
141+
<td> </td>
142+
<td> </td>
143+
<td> </td>
144+
<td>3</td>
145+
<td> </td>
146+
<td> </td>
147+
<td> </td>
148+
</tr>
149+
<tr>
150+
<td> </td>
151+
<td> </td>
152+
<td> </td>
153+
<td> </td>
154+
<td>4</td>
155+
<td> </td>
156+
<td> </td>
157+
</tr>
158+
<tr>
159+
<td> </td>
160+
<td>3</td>
161+
<td>2</td>
162+
<td> </td>
163+
<td> </td>
164+
<td> </td>
165+
<td> </td>
166+
</tr>
167+
<tr>
168+
<td> </td>
169+
<td> </td>
170+
<td> </td>
171+
<td> </td>
172+
<td> </td>
173+
<td> </td>
174+
<td> </td>
175+
</tr>
176+
</tbody>
177+
</table>
178+
179+
<p style="text-align: center;">그림 3</p>
180+
181+
<p>한 덩어리의 빙산이 주어질 때, 이 빙산이 두 덩어리 이상으로 분리되는 최초의 시간(년)을 구하는 프로그램을 작성하시오. 그림 1의 빙산에 대해서는 2가 답이다. 만일 전부 다 녹을 때까지 두 덩어리 이상으로 분리되지 않으면 프로그램은 0을 출력한다.</p>
182+
183+
### 입력
184+
185+
<p>첫 줄에는 이차원 배열의 행의 개수와 열의 개수를 나타내는 두 정수 N과 M이 한 개의 빈칸을 사이에 두고 주어진다. N과 M은 3 이상 300 이하이다. 그 다음 N개의 줄에는 각 줄마다 배열의 각 행을 나타내는 M개의 정수가 한 개의 빈 칸을 사이에 두고 주어진다. 각 칸에 들어가는 값은 0 이상 10 이하이다. 배열에서 빙산이 차지하는 칸의 개수, 즉, 1 이상의 정수가 들어가는 칸의 개수는 10,000 개 이하이다. 배열의 첫 번째 행과 열, 마지막 행과 열에는 항상 0으로 채워진다.</p>
186+
187+
### 출력
188+
189+
<p>첫 줄에 빙산이 분리되는 최초의 시간(년)을 출력한다. 만일 빙산이 다 녹을 때까지 분리되지 않으면 0을 출력한다.</p>
190+
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
#include <iostream>
2+
#include <queue>
3+
#include <cstring>
4+
5+
using namespace std;
6+
7+
#define MAX 300
8+
9+
int dx[] = {0, 0, 1, -1};
10+
int dy[] = {1, -1, 0, 0};
11+
int N, M;
12+
int maps[MAX][MAX];
13+
int upd_maps[MAX][MAX];
14+
int visited[MAX][MAX];
15+
int answer = 0; // 빙산이 두 덩어리가 될 때까지 걸린 시간
16+
int iceberg_cnt = 0; // 빙산의 개수 (빙산이 다 녹으면, 끝)
17+
int dung_cnt = 0; // 덩어리 개수 (덩어리 개수에 따라 끝날 수 있음)
18+
queue<pair<int, int>> q;
19+
20+
void input() {
21+
cin >> N >> M;
22+
for (int i = 0; i < N; i++) {
23+
for (int j = 0; j < M; j++) {
24+
cin >> maps[i][j];
25+
upd_maps[i][j] = maps[i][j];
26+
}
27+
}
28+
}
29+
30+
void copy_map() {
31+
for (int i = 0; i < N; i++) {
32+
for (int j = 0; j < M; j++) {
33+
maps[i][j] = upd_maps[i][j];
34+
}
35+
}
36+
}
37+
38+
void melt_iceberg() {
39+
iceberg_cnt = 0; // 초기화 필요
40+
41+
// (1, 1)부터 (N-2, M-2)까지 for문
42+
for (int x = 1; x < N - 1; x++) {
43+
for (int y = 1; y < M - 1; y++) {
44+
if (maps[x][y] > 0) { // 바다가 아니면
45+
int sea_cnt = 0;
46+
for (int k = 0; k < 4; k++) { // 상하좌우 체크
47+
int nx = x + dx[k];
48+
int ny = y + dy[k];
49+
if (maps[nx][ny] == 0) sea_cnt += 1;
50+
}
51+
int upd_iceberg = maps[x][y] - sea_cnt;
52+
if (upd_iceberg < 0) upd_iceberg = 0;
53+
upd_maps[x][y] = upd_iceberg;
54+
if (upd_maps[x][y] > 0) iceberg_cnt += 1; // 업데이트를 했는데도 아직 빙산이 남아있다면, +1
55+
}
56+
}
57+
}
58+
}
59+
60+
void bfs(int x, int y) {
61+
q.emplace(x, y);
62+
visited[x][y] = 1;
63+
64+
while (!q.empty()) {
65+
int cx = q.front().first;
66+
int cy = q.front().second;
67+
q.pop();
68+
69+
for (int i = 0; i < 4; i++) {
70+
int nx = cx + dx[i];
71+
int ny = cy + dy[i];
72+
73+
if (nx < 0 || nx >= N || ny < 0 || ny >= M) continue;
74+
if (visited[nx][ny] || upd_maps[nx][ny] <= 0) continue;
75+
76+
q.emplace(nx, ny);
77+
visited[nx][ny] = 1;
78+
}
79+
}
80+
}
81+
82+
void count_dung() {
83+
dung_cnt = 0;
84+
for (int x = 1; x < N - 1; x++) {
85+
for (int y = 1; y < M - 1; y++) {
86+
if (visited[x][y]) continue;
87+
if (upd_maps[x][y] > 0) {
88+
bfs(x, y);
89+
dung_cnt += 1;
90+
}
91+
}
92+
}
93+
}
94+
95+
int main() {
96+
input();
97+
98+
while (true) {
99+
melt_iceberg();
100+
101+
if (iceberg_cnt == 0) { // 빙산이 다 녹아버림
102+
cout << 0;
103+
break;
104+
}
105+
106+
count_dung();
107+
answer += 1;
108+
109+
if (dung_cnt >= 2) {
110+
cout << answer;
111+
break;
112+
}
113+
114+
memset(visited, 0, sizeof(visited));
115+
copy_map();
116+
}
117+
118+
return 0;
119+
}

0 commit comments

Comments
 (0)