-
6549 히스토그램에서 가장 큰 직사각형알고리즘/백준 2022. 3. 21. 01:14
백준 6549 히스토그램에서 가장 큰 직사각형 : https://bit.ly/3Jtkc86
6549번: 히스토그램에서 가장 큰 직사각형
입력은 테스트 케이스 여러 개로 이루어져 있다. 각 테스트 케이스는 한 줄로 이루어져 있고, 직사각형의 수 n이 가장 처음으로 주어진다. (1 ≤ n ≤ 100,000) 그 다음 n개의 정수 h1, ..., hn (0 ≤ hi ≤
www.acmicpc.net
[코드 작성 전 정리]
우선 분할 정복으로 풀 것이기 때문에 재귀함수로 구현
필요한 것
① 반(left, right) 나누기
- return max, 높이 정보 필요 (높이는 참조로 전달)
② 합치기
- left, right 중 더 낮은 높이를 기준으로 합치기
③ 합칠 때 겹치는 부분 생각하기
- 겹치는 부분 기준으로 왼쪽, 오른쪽으로 확장하며 max값 계산하기
[문제풀이]
#include <iostream> #include <algorithm> using namespace std; #define ll long long ll area(ll* his, int size, int x, ll& h) { if (size == 1) { h = his[x]; return his[x]; } else { // 나누기 ll lh, rh; int ln = size / 2; int rn = size - ln; ll lmax = max(area(his, ln, x, lh), area(his, rn, x + ln, rh)); //합치기 h = min(lh, rh); ll tmax = h * size; // 겹치는 부분 확인 int lx = x + ln - 1; int rx = lx + 1; ll th = min(his[lx], his[rx]); tmax = max(tmax, th * 2); while (lx > x || rx < x + size - 1) { if (lx > x && (rx == x + size - 1 || his[lx - 1] > his[rx + 1])) { // 왼쪽으로 확장 가능 && (오른쪽 끝까지 도달||오른쪽 확장 높이보다 왼쪽 확장 높이가 더 큰 경우) lx--; th = min(th, his[lx]); } else { rx++; th = min(th, his[rx]); } tmax = max(tmax, th * (rx - lx + 1)); } return max(tmax, lmax); } } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); while (true) { int n; cin >> n; if (n == 0) break; ll* his = new ll[n]; int k; for (int i = 0; i < n; i++) { cin >> k; his[i] = k; } ll h; ll hmax = area(his, n, 0, h); cout << hmax << "\n"; delete[] his; } return 0; }
ll area(ll* his, int size, int x, ll& h) ll* his 히스토그램 높이를 저장하는 배열 int size 현재 확인하고 있는 범위 int x 현재 확인하고 있는 범위의 첫번째 인덱스 값 ll& h 현재 범위의 최소 높이 값 (전달을 위해 참조로 사용) while문 겹치는 부분 기준으로 확장하기 위한 반복문
고려할 점
① 현재 범위(x~x+size-1)를 벗어나지 않으면서 확장할 수 있는가
② 왼쪽, 오른쪽 중 높이가 더 큰 쪽으로 확장할 것
③ 한 쪽 확장이 끝나면 높이 상관없이 나머지 방향으로 확장할 것*주의할 점
long long int 사용하기
[comment]
처음 분할정복 생각한게 맞았는데 괜히 다르게 푼다고 시간이 더 오래걸려서 아쉬운 문제
문제 자체는 그냥 기본 분할정복에서 겹치는 부분 고려하는 것만 추가된 느낌
추가로, 처음에 while문 작성할 때 현재 범위 한정으로 확인하고 안하고가 시간초과에 영향을 줘서 처음부터 생각하지 못한것도 아쉬움
이렇게 푼 방법 외에도 세그멘트 트리, 스택 등의 방식이 있어 추가로 풀어보는 것도 좋을 듯 싶다.
'알고리즘 > 백준' 카테고리의 다른 글
1260 DFS와 BFS (0) 2022.03.25 2805 나무 자르기 (0) 2022.03.23 1920 수 찾기(이분탐색) (0) 2022.03.23 2630 색종이 만들기 (0) 2022.03.17 1068 트리 (1) 2022.03.13