14719-g5 성공

This commit is contained in:
2026-02-23 16:33:43 +09:00
parent 9dafd92505
commit 3777344b56

View File

@@ -0,0 +1,57 @@
# 빗물
import sys
input = sys.stdin.readline
def solution():
h, w = map(int, input().rstrip().split())
blocks = map(int, input().rstrip().split())
stack = []
result = 0
for b in blocks:
if stack:
if b < stack[0]:
stack.append(b)
continue
else:
while stack:
if len(stack) == 1:
stack.pop()
break
result += stack[0] - stack.pop()
stack.append(b)
else:
stack.append(b)
while stack:
if len(stack) == 1:
stack.pop()
break
now = stack.pop()
while stack and stack[-1] <= now:
result += now - stack.pop()
print(result)
return
solution()
"""
걸린 시간: 50분
시간 복잡도: 모든 블럭이 stack에 한번씩 들어갔다가 나오기 때문에 O(n)이다.
해설: 이전에 풀었던 지붕 쌓기와 비슷한 문제이다. 이런 문제들에서 시간을 뺐기지 않고 가려면 좀 공식화해둘 필요가 있다.
내가 기억해야하고 기억하지 않아도 될 것들을 구분해야 하는데,
(1) 시작 블럭의 높이를 기준으로 동등하거나 그 이상의 블럭이 나오면 지금까지 나왔던 것들은 시작 블럭 기준으로 계산하고, 잊어도 됨
1번을 진행하면서 stack의 내용물은 pop되고 새로운 시작 기준점이 잡힌다.
(2) 시작 블럭의 높이를 기준으로 미만인 것들만 있다면 pop될 일이 없기 때문에 다 끝나면 stack에 내용물이 있을 것이다.
이제 stack을 다 비우면서 모든 블럭에 대한 계산을 진행해야 한다.
이때부터는 1번의 역순이다. 왜 why? 시작 블럭 기준으로 미만인 것들만 있었다는 것은 오르내리막이 있어도 최종적으로는 내리막이었다는 뜻이고,
이는 거꾸로 보면 1번에서 하던것처럼 동등하거나 그 이상의 블럭이 무조건 있다는 뜻이다.
따라서 기준점을 stack[-1]로 잡고 1번 방식을 진행하면 된다.
"""