Notice
Recent Posts
Recent Comments
«   2025/02   »
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
Archives
Today
Total
관리 메뉴

블로그 언저리인 무언가

[백준/BOJ] 3321 가장 큰 직사각형 본문

Programming/BOJ

[백준/BOJ] 3321 가장 큰 직사각형

he1fire 2021. 9. 18. 20:26
728x90

문제 : 3321 가장 큰 직사각형

 

3321번: 가장 큰 직사각형

열의 순서를 적절히 바꿔, 2열, 4열, 5열이 서로 붙어있게 놓는다면, 크기가 21인 직사각형을 얻을 수 있다. (2행~8행 * 2,4,5열)

www.acmicpc.net

기본적으로 1로 채워진 가장 큰 정사각형을 찾는 문제이지만

열의 순서를 바꿀 수 있으므로 결국 각 행에 대해서 열의 높이를 정렬하여 누적합을 이용하면

행의 길이를 1씩 늘려가면서 최대 넓이를 구할 수 있다.

이를 구현하게 되면 총 행의 개수 N번, 각 행을 정렬하는데 걸리는 시간이 퀵 정렬 사용 시 MlogM이므로

시간 복잡도가 O(NMlogM)이 되는데 시간제한이 0.6초이기 때문에 이를 O(NM)으로 줄여야 한다.

 

나 같은 경우에는 deque를 사용해 정렬 시간을 O(2M)으로 줄였는데

현재 높이와 인덱스를 pair로 묶어 deque에 저장하고 시작하면

그 이후에서는 현재 높이+1이 되거나 0이 되거나 두 경우중 하나이므로

이를 새로운 두 덱으로 쪼갰다가 합치는 방법으로 구현하게 되면 2번 순회하는 것으로 정렬이 가능하다.


Code

#include <bits/stdc++.h>
#define ll long long
using namespace std;
typedef pair<ll,ll> pll;
ll N, M, ans;
deque<pll> dq, dq1, dq2;
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> N >> M;
    for (int i=0;i<M;i++)
        dq.push_back({0,i});
    for (int i=0;i<N;i++){
        string s;
        cin >> s;
        while (!dq.empty()){
            ll len=dq.front().first, idx=dq.front().second;
            dq.pop_front();
            if (s[idx]=='1')
                dq1.push_back({len+1, idx});
            else
                dq2.push_back({0, idx});
        }
        while (!dq1.empty()){
            dq.push_back(dq1.front());
            dq1.pop_front();
        }
        while (!dq2.empty()){
            dq.push_back(dq2.front());
            dq2.pop_front();
        }
        for (int j=0;j<M;j++)
            ans=max(ans,(j+1)*dq[j].first);
    }
    cout << ans;
    return 0;
}
728x90

'Programming > BOJ' 카테고리의 다른 글

[백준/BOJ] 2873 롤러코스터  (0) 2021.09.20
[백준/BOJ] 20041 Escaping  (0) 2021.09.18
[백준/BOJ] 2573 빙산  (0) 2021.01.08
[백준/BOJ] 1916 최소비용 구하기  (0) 2020.12.04
[백준/BOJ] 9375 패션왕 신혜빈  (0) 2020.12.01
Comments