문제
들어가며
플레의 벽은 높았다..
코드
def largest_rectangle(histogram):
stack = [] # 스택에는 인덱스를 저장합니다.
max_area = 0 # 최대 넓이를 저장할 변수
n = len(histogram)
for i in range(n):
# 현재 높이가 스택의 최상단 높이보다 작으면 넓이를 계산합니다.
while stack and histogram[stack[-1]] > histogram[i]:
height = histogram[stack.pop()] # 스택에서 꺼낸 높이
width = i if not stack else i - stack[-1] - 1 # 너비 계산
max_area = max(max_area, height * width) # 최대 넓이 갱신
stack.append(i) # 현재 인덱스를 스택에 추가
# 히스토그램 끝까지 처리한 후, 스택에 남아 있는 값들 처리
while stack:
height = histogram[stack.pop()] # 스택에서 꺼낸 높이
width = n if not stack else n - stack[-1] - 1 # 너비 계산
max_area = max(max_area, height * width) # 최대 넓이 갱신
return max_area
while True:
l = list(map(int, input().split()))
if l[0] == 0:
break
print(largest_rectangle(l[1:]))
풀이
이 문제는 스택으로 풀 수 있다.
단, 스택엔 히스토그램 수열의 인덱스를 넣는다.
히스토그램
Index: 0 1 2 3 4 5
Height: 2 1 5 6 2 3
초기 상태
stack = [] (스택은 비어 있음)
max_area = 0 (최대 넓이는 초기값으로 설정)
여기서 필요한 건 스택과 최대 넓이이다.
그리고 앞으로 인덱스를 하나씩 탐사하면서 스택에 push를 진행할 거다.
첫 번째 막대 (index = 0, height = 2)
스택이 비어 있으므로 현재 인덱스 0을 스택에 추가한다.
스택 상태는 0이 들어간다.
두 번째 막대 (index = 1, height = 1)
현재 높이 1이 스택의 최상단 높이(height = 2)보다 작으므로 다음과 같은 과정을 거친다.
- 스택에서 값을 꺼낸다. (stack.pop() -> 0)
- 꺼낸 높이 : height = 0이 가리키는 2가 된다.
- 너비 : width = index - stack.peek - 1 = 1 (여기선 스택이 비어 있기 때문에, 현재 인덱스를 넣는다)
- 넓이 : 높이 x 너비 = height x width = 2 x 1 = 2
- 최대 넓이 갱신 : max_area = max(max_area, area) = max(0,2) = 2
그리고 현재 인덱스 1을 스택에 추가한다.
세 번째 막대 (index = 2, height = 5)
스택에 2를 추가한다.
네 번째 막대 (index = 3, height = 6)
스택에 3을 추가한다.
다섯 번째 막대 (index = 4, height = 2)
여기서 중요한 건 높이인 2보다 작거나 같은 값이 나올 때까지, pop을 하고 최대 넓이 갱신을 하는 작업을 무한히 반복한다는 것이다.
- 스택에서 값을 꺼낸다. (stack.pop() -> 3)
- 꺼낸 높이 : height = 3이 가리키는 6이 된다.
- 너비 : width = index - stack.peek - 1 = 4 - 2 - 1 = 1 (3을 빼냈기 때문에, 2가 최대가 된다.)
- 넓이 : 높이 x 너비 = height x width = 6 x 1 = 6
- 최대 넓이 갱신 : max_area = max(max_area, area) = max(2,6) = 6
현재 스택엔 2인 인덱스가 peek에 존재한다.
2가 가리키는 값은 5, 즉 우리가 넣고자 하는 2보다 작다.
이전의 작업을 그대로 진행한다.
- 스택에서 값을 꺼낸다. (stack.pop() -> 2)
- 꺼낸 높이 : height = 2이 가리키는 5이 된다.
- 너비 : width = index - stack.peek - 1 = 4 - 1 - 1 = 2 (2을 빼냈기 때문에, 1이 최대가 된다.)
- 넓이 : 높이 x 너비 = height x width = 5 x 2 = 10
- 최대 넓이 갱신 : max_area = max(max_area, area) = max(6,10) = 10
이와 같은 작업을 처음 히스토그램 수열을 한 번 다 돌때까지 진행한다.
그 이후 만약, 스택에 값이 남아있다면 이전과 똑같이 진행하여 최대 넓이를 갱신한다.
'Algorithm > 백준' 카테고리의 다른 글
[백준] 10000 - 원 영역 문제 풀이(자바,Java) (0) | 2025.03.24 |
---|---|
[백준] 2439 - 탑 문제 풀이(파이썬,Python) (0) | 2025.03.24 |
[백준]11053- 가장 긴 증가하는 부분 수열 문제 풀이(파이썬,Python) (2) | 2025.03.21 |
[백준]2470 - 두 용액 문제 풀이(파이썬,Python) (2) | 2025.03.21 |
[백준]2110 - 공유기 설치 문제 풀이(파이썬,Python) (0) | 2025.03.21 |