이마닷의 블로그

[BOJ] 2573:빙산 본문

problem-solving

[BOJ] 2573:빙산

움나나움 2019. 9. 29. 17:04

 

 

0. 문제

https://www.acmicpc.net/problem/2573

 

2573번: 빙산

첫 줄에는 이차원 배열의 행의 개수와 열의 개수를 나타내는 두 정수 N과 M이 한 개의 빈칸을 사이에 두고 주어진다. N과 M은 3 이상 300 이하이다. 그 다음 N개의 줄에는 각 줄마다 배열의 각 행을 나타내는 M개의 정수가 한 개의 빈 칸을 사이에 두고 주어진다. 각 칸에 들어가는 값은 0 이상 10 이하이다. 배열에서 빙산이 차지하는 칸의 개수, 즉, 1 이상의 정수가 들어가는 칸의 개수는 10,000 개 이하이다. 배열의 첫 번째 행과 열, 마지

www.acmicpc.net

 

1. 문제분석

-  한 칸(노드)에서 시작해서 상하좌우로 인접한 칸을 연속해서 탐색한다는 점에서 DFS 또는 BFS 알고리즘을 사용해 문제를 풀어야 함을 알 수 있다. 별다르게 최단경로를 파악할 필요는 없으므로, DFS나 BFS 둘 다 크게 상관 없을 듯 하지만, 이번에는 DFS를 사용했다.

 

2. 주의할 점

- 문제를 성급히 읽으면 단순히 빙산이 다 녹을때까지의 연수만 계산하는 알고리즘을 짜게된다. 하지만 구해야 하는 것은 "두 덩어리 이상으로 분리되는 최초의 시간"임을 명심하자.

- 단순히 칸 별 값이 0일 때 dfs를 call 하지 않는 것 만으로는 부족하다. 왜냐하면 dfs 함수를 진행하면서, 원래는 빙산이 다 녹지 않았지만(값이 0이 아니었지만), 해당 연도 도중에 0값이 되어버리는 칸도 있기 때문이다. 따라서 방문배열(vtd)를 별도로 사용해준다. 

 

3. 소스코드(C++)

#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#define endl '\n'
#define INF 987654321
using namespace std;
typedef pair<int, int> ii;

int n, m, cnt;
int grid[301][301];
bool vtd[301][301];
int dy[4] = { 0,1,0,-1 };
int dx[4] = { 1,0,-1,0 };

void dfs(int y, int x) {
	vtd[y][x] = true;
	for (int i = 0; i < 4; i++) {
		int ny = y + dy[i];
		int nx = x + dx[i];
		if (ny < 0 || ny >= n || nx < 0 || nx >= m) continue;
		if (vtd[ny][nx]) continue;
		if (grid[ny][nx] == 0) grid[y][x] = max(0, grid[y][x] - 1);
		else dfs(ny, nx);
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	
	int ans = -1;
	cin >> n >> m;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cin >> grid[i][j];
		}
	}

	while (true) {
		cnt = 0;
		ans++;
		memset(vtd, false, sizeof(vtd));
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				if (grid[i][j] == 0 || vtd[i][j]) continue;
				dfs(i, j);
				cnt++;
			}
		}
		if (cnt != 1) break;
	}

	if (cnt == 0) cout << 0;
	else cout << ans;
	return 0;
}

 

4. 여담

- dfs를 통해서 연결된 집단 개수를 파악한다는 점에서 boj2667 단지번호붙이기와 문제 풀이 방식이 비슷하다.

- 또한 상하좌우에 위치한 노드 값에 따라 현재 위치 값이 변화한다는 점에서 boj2636 치즈와도 문제 풀이 방식이 비슷하다.

'problem-solving' 카테고리의 다른 글

[BOJ] 1068:트리  (0) 2020.12.10
[BOJ] 12865:평범한 배낭  (0) 2020.12.08
[BOJ] 2116:주사위 쌓기  (0) 2019.09.22
[BOJ] 2643:색종이 올려 놓기  (0) 2019.09.15
[BOJ] 1162:도로포장  (0) 2019.09.07
Comments