본문 바로가기

Algorithm

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

스택으로 풀 수 있는 정답률 24퍼센트의 히스토그램에서 가장 큰 직사각형 문제이다.

 

n개의 직사각형이 있고 n개의 직사각형으로 만들 수 있는 가장 큰 직사각형의 넓이를 출력하면 되는 문제이다.

n제한이 100,000이기 때문에 모든 경우를 해보는 O(n^2)의 방법은 시간 초과이다.

스택을 활용한다면 O(n)만에 문제를 풀 수 있다.

 

문제를 푸는 키포인트는

직사각형의 번호를 스택에 높이를 기준으로 오름차순으로 넣어준다는 점이다.

 

문제를 푸는 과정을 설명하자면

0부터 n-1까지의 for문을 돌면서

만약 i번째 직사각형의 높이가 스택에 가장 윗부분 직사각형의 높이보다 낮다면

가능한 넓이를 구하면서 가장 큰 값을 찾아낸다.

마지막으로 스택에 남아있는 것들도 처리해준다

 

i는 현재 위치 즉 오른쪽 위치를 나타내고 stack.peek()은 왼쪽 위치를 나타낸다.

스택에는 높이 오름차순으로 직사각형의 번호가 들어가므로

스택에 마지막에있는 직사각형의 높이를 기준으로 너비를 계산하며 넓이를 구한다.

스택이 빌때까지 pop 해주며 직사각형의 높이와 가능한 너비를 계산해서 가장 큰 넓이를 찾는다.

 

이해하기 굉장히 어려운 문제이다.

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
40
41
42
43
44
45
46
47
48
49
 
public class Q6549 {
 
    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        while(true) {
            StringTokenizer st = new StringTokenizer(reader.readLine());
            int n = Integer.parseInt(st.nextToken());
            if(n == 0break;
            long [] a = new long[n];
            for(int i=0; i<n; i++) {
                a[i] = Long.parseLong(st.nextToken());
            }
            Stack<Integer> s = new Stack<>();
            long ans = 0;
            for(int i=0; i<n; i++) {
                while(!s.isEmpty() && a[s.peek()] > a[i]) {
                    Long height = a[s.pop()];
                    int width = i;
                    if(!s.isEmpty()) {
                        width = i-s.peek()-1;
                    }
                    if(ans < width * height) {
                        ans = width * height;
                    }
                }
                s.push(i);
            }
            while(!s.isEmpty()) {
                long height = a[s.pop()];
                int width = n;
                if(!s.isEmpty()) {
                    width = n-s.peek()-1;
                }
                if(ans < width * height) {
                    ans = width * height;
                }
            }
            System.out.println(ans);
        }
    }
 
}
 
 

https://www.acmicpc.net/problem/1725

 

1725번: 히스토그램

문제 히스토그램에 대해서 알고 있는가? 히스토그램은 아래와 같은 막대그래프를 말한다. 각 칸의 간격은 일정하고, 높이는 어떤 정수로 주어진다. 위 그림의 경우 높이가 각각 2 1 4 5 1 3 3이다. 이러한 히스토그램의 내부에 가장 넓이가 큰 직사각형을 그리려고 한다. 아래 그림의 빗금 친 부분이 그 예이다. 이 직사각형의 밑변은 항상 히스토그램의 아랫변에 평행하게 그려져야 한다. 주어진 히스토그램에 대해, 가장 큰 직사각형의 넓이를 구하는 프로그램을

www.acmicpc.net

똑같은 문제이다.

'Algorithm' 카테고리의 다른 글

백준 2231 분해합 Java  (6) 2019.07.29
백준 1712 손익분기점 Java  (0) 2019.07.26
백준 3111 검열 Java  (0) 2019.07.11
백준 9935 문자열 폭발 Java  (0) 2019.07.10
백준 5582 공통 부분 문자열 & 9251 LCS & 9252 LCS 2 Java  (0) 2019.06.28