Uknow's Lab.
article thumbnail

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

 

2573번: 빙산

첫 줄에는 이차원 배열의 행의 개수와 열의 개수를 나타내는 두 정수 N과 M이 한 개의 빈칸을 사이에 두고 주어진다. N과 M은 3 이상 300 이하이다. 그 다음 N개의 줄에는 각 줄마다 배열의 각 행을

www.acmicpc.net

난이도 : 골드 4
태그 : 구현, 그래프 이론, 그래프 탐색, 너비 우선 탐색, 깊이 우선 탐색

 

 

1. 설명

얼음을 녹이면서 덩어리가 두개가 되는 시점을 찾는 문제입니다.

얼음을 녹이는 구현 부분에 약간의 시뮬레이션 요소가 들어갔다고 볼 수 있을 것 같네요.

얼음이 몇 덩어리인지 확인하는 부분은 DFS / BFS 를 사용할 수 있을 것 같은데,

저는 DFS를 사용해 풀이하였습니다.

 

 

 

2. 접근 방법

1. 얼음을 녹인다

얼음이 녹음으로써 바로 옆 칸의 결과에 영향을 줄 수 있기 때문에 맵을 하나 더 만든 후 결과값을 적용시켜야 합니다.

2. 모든 정점에서 DFS를 수행하며 얼음 덩어리가 총 몇개 있는지 확인한다.

3 - 1. 얼음 덩어리가 1개라면 1번 과정으로 돌아간다.

3 - 2. 얼음 덩어리가 2개 이상이라면 결과값을 출력하고 종료한다.

3 - 3. 얼음 덩어리가 0개라면 2개 이상으로 쪼개지기 전에 다 녹은 것이므로, 0을 출력하고 종료한다.

 

 

 

3. 소스코드

<kotlin />
import java.util.StringTokenizer var n = 0 var m = 0 val dx = intArrayOf(0, 0, -1, 1) val dy = intArrayOf(-1, 1, 0, 0) lateinit var visited: Array<Array<Boolean>> lateinit var map: Array<Array<Int>> var iceGroupCnt = 0 fun main() = with(System.`in`.bufferedReader()) { val nm = readLine().split(" ").map { it.toInt() } n = nm[0] m = nm[1] map = Array(n) { val st = StringTokenizer(readLine()) Array(m) { st.nextToken().toInt() } } var year = 0 while (true) { year++ melt() visited = Array(n) { Array(m) { false } } iceGroupCnt = 0 for (i in 0 until n) { for (j in 0 until m) { if (dfs(i, j)) iceGroupCnt++ if (iceGroupCnt >= 2) { println(year) return } } } if (iceGroupCnt == 0) { println(0) return } } } fun dfs(x: Int, y: Int): Boolean { if (map[x][y] == 0 || visited[x][y]) return false visited[x][y] = true for (i in 0 until 4) { val nx = x + dx[i] val ny = y + dy[i] if (nx !in 0 until n || ny !in 0 until m || visited[nx][ny] || map[nx][ny] == 0) continue dfs(nx, ny) } return true } fun melt() { val meltMap = Array(n) { Array(m) { 0 } } for (i in 0 until n) { for (j in 0 until m) { if (map[i][j] == 0) continue for (k in 0 until 4) { val nx = i + dx[k] val ny = j + dy[k] if (nx !in 0 until n || ny !in 0 until m || map[nx][ny] != 0) continue meltMap[i][j]++ } } } for (i in 0 until n) { for (j in 0 until m) { map[i][j] -= meltMap[i][j] if (map[i][j] < 0) map[i][j] = 0 } } }

 

 

 

 

4. 후기

꽤 비슷한 유형을 여러 번 풀어봤던 탓에,

금방 풀 수 있었 던 것 같네요.

DFS는 역시 최고야. 짜릿해.

profile

Uknow's Lab.

@유노 Uknow

인생은 Byte와 Double 사이 Char다. 아무말이나 해봤습니다.