-
백준 - 히스토그램에서 가장 큰 직사각형 (6549) [C++]문제 풀이/백준 2024. 11. 28. 15:50반응형
이 문제는 분할 정복을 이용해서 풀었다.
원래 세그먼트 트리로 푼다고 알고 있어서 세그먼트 트리를 만들고 있었는데, init 함수를 만들다 이미 값 계산이 끝난다는 사실을 알게 되었다.
이 문제에서 가장 핵심은 절반으로 쪼갠 mid에 걸쳐 넓이의 최댓값을 구하는 것이다.
이 부분을 해결하기 못했고, mid에서부터 좌우를 비교하여 더 높이가 높은 쪽을 선택하는 신박한 방법을 알게 되었다.
이를 통해 start ~ end까지 한번씩만 탐색하여 가운데에 걸친 넓이를 구할 수 있었다.
이 방식으로 해결할 경우 O(N log N) 시간이 걸릴 것으로 예측된다. 정확히 절반씩을 쪼개며 들어가므로 log N 만큼의 높이가 생기고, 각 높이에서 N개의 노드를 순회할 것이기 때문이다.
#include <iostream> #include <utility> #include <algorithm> using namespace std; typedef long long LL; #define MAX 100000 LL input[MAX]; int n; LL init(int node, int start, int end) { if (start == end) { return input[start]; } int mid = (start + end) / 2; LL left = init(node * 2, start, mid); LL right = init(node * 2 + 1, mid + 1, end); LL tempMax = input[mid]; LL lowest = input[mid]; LL tempLeft = mid; LL tempRight = mid; while (true) { if (tempLeft == start && tempRight == end) { break; } if (tempLeft - 1 < start) { tempRight++; lowest = min(lowest, input[tempRight]); } else if (tempRight + 1 > end) { tempLeft--; lowest = min(lowest, input[tempLeft]); } else { if (input[tempLeft - 1] >= input[tempRight + 1]) { tempLeft--; lowest = min(lowest, input[tempLeft]); } else { tempRight++; lowest = min(lowest, input[tempRight]); } } int length = tempRight - tempLeft + 1; tempMax = max(tempMax, length * lowest); } return max(tempMax, max(left, right)); } int main() { ios_base::sync_with_stdio(0); cin.tie(0); while (true) { cin >> n; if (n == 0) { break; } for (int i = 0; i < n; i++) { cin >> input[i]; } LL result = init(1, 0, n - 1); cout << result << '\n'; } return 0; }
반응형'문제 풀이 > 백준' 카테고리의 다른 글
백준 - 두 용액 (2470) [C++] (0) 2024.11.29 백준 - 수열과 쿼리 17 (14438) [C++] (0) 2024.11.28 백준 - 가운데를 말해요 (1655) [C++] (0) 2024.11.04 백준 - 마법사 상어와 비바라기 (21610) [C++] (2) 2024.10.06 백준 - 컨베이어 벨트 위의 로봇 (20055) [C++] (0) 2024.09.26