2 분 소요

1. 문제

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

  • 그래프 문제
// 문제
지구 온난화로 인하여 북극의 빙산이 녹고 있다. 
빙산을 그림 1 같이 2차원 배열에 표시한다고 하자. 
빙산의  부분별 높이 정보는 배열의  칸에 양의 정수로 저장된다. 
빙산 이외의 바다에 해당되는 칸에는 0 저장된다. 
그림 1에서 빈칸은 모두 0으로 채워져 있다고 생각한다.
 	 	 	 	 	 	 
 	2	4	5	3	 	 
 	3	 	2	5	2	 
 	7	6	2	4	 	 
 	 	 	 	 	 	 
그림 1. 행의 개수가 5이고 열의 개수가 7 2차원 배열에 저장된 빙산의 높이 정보

빙산의 높이는 바닷물에 많이 접해있는 부분에서  빨리 줄어들기 때문에, 
배열에서 빙산의  부분에 해당되는 칸에 있는 높이는 일년마다 
 칸에 동서남북  방향으로 붙어있는 0 저장된 칸의 개수만큼 줄어든다. 
,  칸에 저장된 높이는 0보다  줄어들지 않는다. 
바닷물은 호수처럼 빙산에 둘러싸여 있을 수도 있다. 
따라서 그림 1 빙산은 일년후에 그림 2 같이 변형된다.

그림 3 그림 1 빙산이 2 후에 변한 모습을 보여준다. 
2차원 배열에서 동서남북 방향으로 붙어있는 칸들은 서로 연결되어 있다고 말한다. 
따라서 그림 2 빙산은  덩어리이지만, 
그림 3 빙산은  덩어리로 분리되어 있다.
 	 	 	 	 	 	 
 	 	2	4	1	 	 
 	1	 	1	5	 	 
 	5	4	1	2	 	 
 	 	 	 	 	 	 
그림 2
 	 	 	 	 	 	 
 	 	 	3	 	 	 
 	 	 	 	4	 	 
 	3	2	 	 	 	 
 	 	 	 	 	 	 
그림 3

 덩어리의 빙산이 주어질 , 
 빙산이  덩어리 이상으로 분리되는 
최초의 시간() 구하는 프로그램을 작성하시오. 
그림 1 빙산에 대해서는 2 답이다. 
만일 전부  녹을 때까지  덩어리 이상으로 분리되지 않으면 
프로그램은 0 출력한다.

// 입력
 줄에는 이차원 배열의 행의 개수와 열의 개수를 나타내는 
 정수 N과 M이  개의 빈칸을 사이에 두고 주어진다. 
N과 M은 3 이상 300 이하이다.  다음 N개의 줄에는  줄마다 
배열의  행을 나타내는 M개의 정수가  개의  칸을 사이에 두고 주어진다. 
 칸에 들어가는 값은 0 이상 10 이하이다. 
배열에서 빙산이 차지하는 칸의 개수, 
, 1 이상의 정수가 들어가는 칸의 개수는 10,000  이하이다. 
배열의  번째 행과 , 마지막 행과 열에는 항상 0으로 채워진다.

// 출력
 줄에 빙산이 분리되는 최초의 시간() 출력한다. 
만일 빙산이  녹을 때까지 분리되지 않으면 0 출력한다.

// 예제 입력 1 
5 7
0 0 0 0 0 0 0
0 2 4 5 3 0 0
0 3 0 2 5 2 0
0 7 6 2 4 0 0
0 0 0 0 0 0 0

// 예제 출력 1 
2


2. 핵심 아이디어


3. Python 문제풀이

import sys
from collections import deque
input = sys.stdin.readline

def bfs(x, y) :
  q = deque([(x, y)])
  visited[x][y] = 1
  lst = []

  while q :
    x, y = q.popleft()
    sea = 0
    for i in range(4) :
      nx = x + dx[i]
      ny = y + dy[i]
      if 0 <= nx < n and 0 <= ny < m :
        if not graph[nx][ny] :
          sea += 1
        elif graph[nx][ny] and not visited[nx][ny] :
          q.append((nx, ny))
          visited[nx][ny] = 1
    if sea > 0 :
      lst.append((x, y, sea))
  for x, y, sea in lst :
    graph[x][y] = max(0, graph[x][y] - sea)

  return 1

n, m = map(int, input().split())
graph = [list(map(int, input().split())) for _ in range(n)]
ice = []

for i in range(n) :
  for j in range(m) :
    if graph[i][j] :
      ice.append((i, j))

dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
year = 0

while ice :
  visited = [[0] * m for _ in range(n)]
  dele = []
  group = 0
  for i, j in ice :
    if graph[i][j] and not visited[i][j] :
      group += bfs(i, j)
    if graph[i][j] == 0 :
      dele.append((i, j))
  if group > 1 :
    print(year)
    break
  ice = sorted(list(set(ice) - set(dele)))
  year += 1

if group < 2 :
  print(0)


4. Java 문제풀이


댓글남기기