59 lines
2.7 KiB
Python
59 lines
2.7 KiB
Python
# 창고 다각형
|
|
|
|
import sys
|
|
|
|
input = sys.stdin.readline
|
|
|
|
def solution():
|
|
n = int(input().rstrip())
|
|
|
|
line = sorted([tuple(map(int, input().rstrip().split())) for _ in range(n)])
|
|
|
|
high_stack = []
|
|
result = 0
|
|
|
|
for x, y in line:
|
|
if not high_stack:
|
|
high_stack.append((x, y))
|
|
continue
|
|
|
|
last_pop = ()
|
|
while len(high_stack) != 0 and high_stack[-1][1] <= y:
|
|
last_pop = high_stack.pop()
|
|
|
|
if len(high_stack) == 0:
|
|
result += (x - last_pop[0])*last_pop[1]
|
|
|
|
high_stack.append((x, y))
|
|
|
|
for _ in range(len(high_stack)):
|
|
x, y = high_stack.pop()
|
|
if len(high_stack) == 0:
|
|
result += y
|
|
else:
|
|
result += (x - high_stack[-1][0])*y
|
|
|
|
print(result)
|
|
|
|
return
|
|
|
|
|
|
solution()
|
|
|
|
"""
|
|
걸린 시간: 40분
|
|
|
|
시간 복잡도: while문이 있지만 어차피 전체적으로는 요소 기준으로 봤을 때 stack에 들어가고 나오는거 한번씩이기 때문에 O(n)이다.
|
|
|
|
해설: 가장 높은 놈(top)을 만날때까지는 그냥 max 갱신해가며 하면 되지만 내리막에서는 작은 놈을 갱신하며 가야된다.
|
|
근데 내려갈때 무지성으로 작은 놈만 갱신해가면, 갑자기 큰 놈이 나왔을 때 우물형태가 생기므로 조건에 위배되기 때문에 지금까지 구했던것을 다시 계산해야된다.
|
|
근데 그러면 돌아가서 다시 계산하기 때문에 O(n^2)이 되버린다.
|
|
따라서 작은 놈을 계속 가져가되, 그것보다 큰 놈이 나왔을 때 이전 작은 것들을 버리는 방식으로 하면 된다. 이건 stack을 쓰면 쉽게 구현이 가능하다.
|
|
따라서 스택에 넣는 조건을 내가 들어갈때 스택에(이전 놈들) 나보다 작은 애들은 다 pop하고 들어간다. 그렇게 끝에는 top과 완벽한 내리막만 남는다.
|
|
이제 stack에서 pop을 하면서 pop한 녀석과 아직 stack에 남아있는 놈과의 거리로 넓이를 계산하고 마지막에 나오는 녀석은 너비가 1이므로 계산하면 된다.
|
|
한 가지 문제는 오르막에서도 이 조건을 그대로 쓰면 나보다 작은 이전 놈들의 권리가 없어진다.
|
|
따라서 내가 스택에 들어갈 때 나보다 작은 놈들을 다 pop했는데 stack이 비어 있다면 아직 top이 없었던 것이기 때문에 마지막에 나온 애는 넓이를 계산해준다.
|
|
|
|
다른 풀이로는 가장 높은 놈을 기준으로 오르막과 내리막이 나올 수밖에 없으므로, 왼쪽에서 top까지 max를 갱신해가며 넓이 구하고,
|
|
오른쪽에서 top까지 반대로 가면서 max 갱신해가며 넓이 구해서 더하면 끝이긴 하네.
|
|
""" |