알고리즘 문제/[백준]

[백준] 6549 히스토그램에서 가장 큰 직사각형

latter2005 2021. 1. 22. 03:28

문제 주소 : www.acmicpc.net/problem/6549

 

6549번: 히스토그램에서 가장 큰 직사각형

입력은 테스트 케이스 여러 개로 이루어져 있다. 각 테스트 케이스는 한 줄로 이루어져 있고, 직사각형의 수 n이 가장 처음으로 주어진다. (1 ≤ n ≤ 100,000) 그 다음 n개의 정수 h1, ..., hn (0 ≤ hi ≤

www.acmicpc.net

fast io 미적용

문제 확인

 

특별한 알고리즘이 필요 없는 스택을 이용한 구현 문제입니다. 

 

풀이

 

입력받은 직사각형의 높이와 i 값을 스택에 쌓으면서 기록합니다. 다음 나오는 직사각형의 높이에 따라 다음과 같이 동작합니다.

  • 다음 직사각형의 높이에 높다면 계속해서 스택을 쌓아갑니다.
  • 높이가 같은 경우 시작 지점인 i값을 기록해 두었으므로 스택에 넣을 필요가 없습니다.
  • 다음 직사각형의 높이가 낮다면 스텍에서 만들 수 있는 직사각형만큼 체크를 합니다. 

만들 수 있는 직사각형의 가로길이는 i - idx[top] 이며 높이는 stack[top]입니다. 스택에 기록된 직사각형 들은 오름차순으로 정렬되어 있는 상태이므로 스택 아래에 저장되어 있는 직사각형의 가로길이는 사이에 포함된 직사각형들을 포함할 수 있기 때문에 현재 지점인 i, 높이에 해당하는 막대의 위치 idx[top]과의 차이가 됩니다. 이러한 과정을 stack[top] > h일 때까지 반복합니다.

i=3에서 i=4가 되는 경우 2, 3에 해당하는 히스토그램에서 만들 수 있는 직사각형을 체크하고 스택에서 빼냅니다. 이때 i=4에 해당하는 막대의 h값만 기록해도 되는 이유는 시작 위치가 이미 이전에 기록된 상태이기 때문에 바꿀 필요가 없습니다.

 

모든 탐색이 끝나고 나면 직사각형의 가로 길이는 n - idx[top]이 되며 스택에 남은 막대들을 같은 방식으로 계산합니다.

 

코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
using namespace std;
int main() {
    cin.tie(NULL);
    ios::sync_with_stdio(false);
    int stack[100001= { -1 }, idx[100001], top = 0;
    int n;
    cin >> n;
    while (n) {
        long long max = 0size;
 
        for (int i = 0, t; i < n; i++) {
            cin >> t;
            if (stack[top] > t) {//다음 직사각형이 작은 경우
                do {
                    size = ((long long)i - idx[top]) * stack[top];
                    max = max < size ? size : max;
                    --top;
                } while (stack[top] > t);//만들 수 있는 직사각형 체크
                if (t)
                    stack[++top] = t;//i값은 남아있는 흔적을 이용하고, h값만 기록
            }
            else if (t && stack[top] < t) {//직사각형이 큰 경우
                stack[++top] = t;
                idx[top] = i;//스텍에 추가
            }
 
        }
        while (top != 0) {//남은 히스토그램 처리
            size = ((long long)n - idx[top]) * stack[top];
            max = max < size ? size : max;
            --top;
        }
        cout << max << '\n';
        cin >> n;
    }
}
 
 
cs
반응형

'알고리즘 문제 > [백준]' 카테고리의 다른 글

[백준] 2534 카드 배열  (0) 2021.01.25
[백준] 2252 줄 세우기  (0) 2021.01.24
[백준] 16287 Parcel  (0) 2021.01.21
[백준] 1256 사전  (0) 2021.01.20
[백준] 7579 앱  (0) 2021.01.18