diff --git a/workbook_8708/2304-s2.py b/workbook_8708/2304-s2.py new file mode 100644 index 0000000..fb30432 --- /dev/null +++ b/workbook_8708/2304-s2.py @@ -0,0 +1,59 @@ +# 제목 + +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 갱신해가며 넓이 구해서 더하면 끝이긴 하네. +""" \ No newline at end of file