본문 바로가기

알고리즘/🥇 골드

백준 14719 빗물 파이썬 풀이

728x90

난이도 : 골드5
풀이일 : 04241
https://www.acmicpc.net/problem/14719

14719번: 빗물

첫 번째 줄에는 2차원 세계의 세로 길이 H과 2차원 세계의 가로 길이 W가 주어진다. (1 ≤ H, W ≤ 500) 두 번째 줄에는 블록이 쌓인 높이를 의미하는 0이상 H이하의 정수가 2차원 세계의 맨 왼쪽 위치

www.acmicpc.net


링크로 이동하기 귀찮은 분들을 위한 문제 캡쳐


풀이 과정

  • 인덱스 활용을 위해 enumerate 사용
  • 배열 안에서 max 탐색
  • max 좌, 우 방향 두 번째 max 탐색
  • 빗물 += 두 번째 max - 각 인덱스에 있는 값들의 높이
    • 인덱스 범위 : 두 번째 max ~ max (좌, 우 반대)
  • 좌, 우 모두 방향은 유지 탐색

풀이 코드

# 1. 인덱스 활용을 위해 enumerate
# 2. 배열 안에서 max 탐색
# 3. max 좌 우로 다음 sec_max 탐색
# 4. 빗물 += sec_max - arr[i]
#    범위 sec_max_idx ~ max_idx
# 5. 왼쪽은 계속 왼쪽으로만, 오른쪽은 계속 오른쪽으로만 탐색

import sys

def left(start, num):    # 좌측 탐색
    global sell
    arr = block[start:num]
    temp = max(arr, key=lambda x: x[1])
    for i in range(temp[0], num):
        sell += temp[1] - arr[i][1]
    if temp[0] > 0:
        left(start, temp[0])
    else:
        return

def right(num, end):    # 우측 탐색
    global sell
    arr = block[num:end]
    temp = max(arr, key=lambda x: x[1])
    for i in range(temp[0]-num):
        sell += temp[1] - arr[i][1]
    if temp[0] < w-1:
        right(temp[0]+1, end)
    else:
        return

h, w = map(int, sys.stdin.readline().split())
block = list(enumerate(map(int, sys.stdin.readline().split())))
sell = 0    # 빗물 고인 영역

maxi = max(block, key=lambda x:x[1])

if maxi[0] > 0:    # 탐색할 구간 존재 시 함수 실행
    left(0, maxi[0])
if maxi[0] < w-1:
    right(maxi[0]+1, w)

print(sell)

느낀점
너무 더럽게 푼 것 같은데 통과 되어서 놀랐다.
자신있게 제출하고 맞았습니다를 보고 싶다
최대값 조회 시, 두 번째 값을 기준으로 하기 위해 사용한 람다 식이 익숙하지 않다.
비슷하게 사용할 수 있는 곳이 있다면 자주 사용해보고, 익숙해지자.