[Baekjoon] 2573. 빙산

2025. 2. 7. 12:23·코딩테스트/Python
728x90
반응형

🔗 Problem Link

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


❔Thinking

  • 2차원 배열에 빙산의 높이가 주어질 때, 일년마다 상하좌우에 있는 0의 개수만큼 높이가 줄어든다
  • 한 덩어리의 빙산이 두개 이상의 덩어리가 되는 최소한의 년수를 반환한다.
  • 상하좌우로 붙어 있어야 한 덩어리에 속한다. (즉, 대각선을 포함되지 않는다.)

💻Solution

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

N, M = map(int, input().split())
board = [list(map(int, input().split())) for _ in range(N)]
total_ice = sum(cell > 0 for row in board for cell in row)

directions = [(1, 0), (-1, 0), (0, 1), (0, -1)]

def ice_check():
    """
    현재 board에서 연결된 빙산 덩어리의 수를 반환하는 함수.
    """
    if total_ice == 0:
        return 0

    visited = [[False] * M for _ in range(N)]
    component_count = 0

    for i in range(N):
        for j in range(M):
            if board[i][j] > 0 and not visited[i][j]:
                component_count += 1
                if component_count >= 2:
                    # 두 덩어리가 있으면 더 이상 탐색할 필요 없이 바로 반환
                    return component_count

                # BFS로 연결된 모든 빙산 칸 방문 처리
                queue = deque([(i, j)])
                visited[i][j] = True
                while queue:
                    ci, cj = queue.popleft()
                    for di, dj in directions:
                        ni, nj = ci + di, cj + dj
                        if 0 <= ni < N and 0 <= nj < M:
                            if board[ni][nj] > 0 and not visited[ni][nj]:
                                visited[ni][nj] = True
                                queue.append((ni, nj))
    return component_count

def ice_melting():
    """
    각 빙산 칸 주변의 물의 개수만큼 빙산이 녹는 것을
    동시에 반영하여 board를 갱신하는 함수.
    """
    global total_ice
    # 녹아야 할 칸과 그때 녹는 양을 저장할 리스트
    melting = []
    
    # 전체 board를 순회하며 녹는 양 계산
    for i in range(N):
        for j in range(M):
            if board[i][j] > 0:
                water_count = 0
                for di, dj in directions:
                    ni, nj = i + di, j + dj
                    if 0 <= ni < N and 0 <= nj < M:
                        if board[ni][nj] == 0:
                            water_count += 1
                if water_count:
                    melting.append((i, j, water_count))
    
    # 동시에 녹이기 위해 미리 계산한 녹는 양을 반영
    for i, j, water in melting:
        new_height = board[i][j] - water
        if new_height <= 0:
            if board[i][j] > 0:
                total_ice -= 1
            board[i][j] = 0
        else:
            board[i][j] = new_height

year = 0
while total_ice:
    year += 1
    ice_melting()
    if ice_check() >= 2:
        print(year)
        break
else:
    print(0)

🗝️keypoint

  1. 주변의 0의 개수를 파악해 곧바로 높이를 수정하면, 새롭게 0이 되는 빙산에 따라 주변 빙산의 높이가 영향을 받는다.
  2. while, for문에는 else를 두어 끝까지 반복문을 수행한 경우의 행동을 정의할 수 있다. 
저작자표시 (새창열림)

'코딩테스트 > Python' 카테고리의 다른 글

[Baekjoon] 2565. 전깃줄  (0) 2025.02.11
[Programmers] Level 2. 충돌위험 찾기  (0) 2025.02.09
[Programmers] Level 2. 3xn 타일링  (0) 2025.02.05
[Baekjoon] 1062. 가르침  (0) 2025.02.02
[Programmers] Level 2. 양궁대회  (1) 2025.01.31
'코딩테스트/Python' 카테고리의 다른 글
  • [Baekjoon] 2565. 전깃줄
  • [Programmers] Level 2. 충돌위험 찾기
  • [Programmers] Level 2. 3xn 타일링
  • [Baekjoon] 1062. 가르침
swwho
swwho
일상을 데이터화하다
  • swwho
    하루한장
    swwho
  • 전체
    오늘
    어제
    • 분류 전체보기 (188)
      • ML_DL (39)
        • MUJAKJUNG (무작정 시리즈) (18)
        • 딥러닝 공부하기 (21)
      • 데이터사이언스 (1)
        • EDA (1)
        • 데이터과학을 위한 통계 (0)
      • 데이터엔지니어링 (2)
      • 논문리뷰 (2)
        • Computer Vision (2)
      • Python 활용하기 (12)
      • 코딩테스트 (127)
        • Python (109)
        • MySQL (14)
      • Git (3)
      • MySQL 활용하기 (0)
      • 일상 이야기 (1)
  • 블로그 메뉴

    • 홈
    • 태그
  • 최근 글

  • 250x250
  • hELLO· Designed By정상우.v4.10.3
swwho
[Baekjoon] 2573. 빙산
상단으로

티스토리툴바