강남역에 엄청난 폭우가 쏟아진다고 가정합시다. 정말 재난 영화에서나 나올 법한 양의 비가 내려서, 고층 건물이 비에 잠길 정도입니다.
그렇게 되었을 때, 건물과 건물 사이에 얼마큼의 빗물이 담길 수 있는지 알고 싶은데요. 그것을 계산해 주는 함수 trapping_rain을 작성해 보려고 합니다.
함수 trapping_rain은 건물 높이 정보를 보관하는 리스트 buildings를 파라미터로 받고, 담기는 빗물의 총량을 리턴해 줍니다.
예를 들어서 파라미터 buildings로 [3, 0, 0, 2, 0, 4]가 들어왔다고 합시다. 그러면 0번 인덱스에 높이 3의 건물이, 3번 인덱스에 높이 2의 건물이, 5번 인덱스에 높이 4의 건물이 있다는 뜻입니다. 1번, 2번, 4번 인덱스에는 건물이 없습니다.
그러면 아래의 사진에 따라 총 10 만큼의 빗물이 담길 수 있습니다. 따라서 trapping_rain 함수는 10을 리턴하는 거죠.
이번에는 파라미터 buildings로 [0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1]가 들어왔다고 합시다. 그러면 아래의 사진에 따라 총 6 만큼의 빗물이 담길 수 있습니다. 따라서 trapping_rain 함수는 6을 리턴하는 거죠
이 정보를 기반으로, trapping_rain 함수를 작성해 보세요!
예시
# 테스트
print(trapping_rain([3, 0, 0, 2, 0, 4]))
print(trapping_rain([0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1]))
10
6
[해설]
빗물이 담기는 양을 계산하려면 각각의 index에 해당하는 빗물의 양을 모두 더하면 된다. 각각의 index에 빗물의 양을 계산하려면 규칙을 파악해야 한다.
먼저 예시를 보고 알 수 있는 점은 0번 인덱스와 마지막 인덱스에는 빗물이 담길 수 없다. 그리고 더 큰 건물들 사이에 끼어 있으면 빗물이 담긴다는 것을 알 수 있다. 그리고 구해야 할 것은 얼마의 빗물이 담기는지 알아야 된다.
다음 그림에서 4번 인덱스를 보자. 4번 인덱스는 왼쪽으로 가장 높은 건물은 3번 인덱스에 있고, 4번 인덱스의 오른쪽으로 가장 높은 건물은 7번 인덱스에 있다. 3번 인덱스의 건물은 높이가 2이고, 7번 인덱스의 건물은 높이가 3인다. 그리고 4번 인덱스에 담긴 빗물의 양은 1이다.
물이 담기는 것은 4번 인덱스 건물의 높이인 1부터 시작해서, 3번 인덱스와 7번 인덱스의 건물 중 더 낮은 높이인 2까지이다. 그래서 1 만큼의 빗물만 담기는 것이다.
1. 현재 인덱스의 왼쪽에서 가장 높은 건물의 높이를 구한다.
2. 현재 인덱스의 오른쪽에서 가장 높은 건물의 높이를 구한다.
3. 왼쪽과 오른쪽에서 구한 최대값은 2개인데 이 중 더 낮은 건물의 높이를 구한다.
4. 그 높이에서 현재 인덱스에 있는 건물의 높이를 뺀다.
def trapping_rain(buildings):
total=0
for i in range(1,len(buildings)-1):
max_left=max(buildings[:i])
max_right=max(buildings[i:])
upper_bound = min(max_left,max_right)
total += max(0,upper_bound-buildings[i])
return total
# 테스트
print(trapping_rain([3, 0, 0, 2, 0, 4]))
print(trapping_rain([0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1]))
'알고리즘 > 알고리즘 문제' 카테고리의 다른 글
[파이썬] [백준 2606번] 바이러스 (DFS) (0) | 2021.04.07 |
---|---|
[파이썬] [백준 - 2667번] 단지 번호 붙이기 (DFS) (0) | 2021.04.07 |
[파이썬] [백준 - 2798번] 블랙잭 (Brute Force) (0) | 2021.04.02 |
[파이썬] [백준 -1914번] 하노이 탑 (재귀함수) (0) | 2021.04.02 |
[파이썬] [백준 -2805번] 나무 자르기 (Dynamic Programming) (0) | 2021.03.29 |