※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※

 

이번에 볼 문제는 백준 23000번 문제인 L Shaped Plots이다.
문제는 아래 링크를 확인하자.

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

 

문제에서 찾아야하는 L모양은 (1) 어떠한 교차점이 있으며, (2) 그 교차점에서 2 이상의 \(k\)에 대해 수직으로 \(k\)칸 및 \(2k\)칸이 뻗은 모양으로 생각할 수 있다. 이와 같이 생각하면 해당 모양은 각 칸에서 수직으로 뻗어나갈 두 방향을 고르는 방법 네 가지와 어느 방향으로 더 많은 칸을 연결할지의 두 가지의 곱 8가지 경우를 살피는 것으로 모든 경우의 수를 고려할 수 있음을 알 수 있다.

 

다만, 모든 L모양 상태에 직접 접근하기에는 경우의 수가 너무 많아질 수 있으므로, 각 칸에 대하여 상하좌우방향으로 이을 수 있는 칸의 개수의 최댓값을 미리 전처리해두자.

 

아래는 제출한 소스코드이다.

#include <iostream>
#include <cstring>
using namespace std;
typedef long long ll;

int R, C;
int A[1002][1002];
int sR[1002][1002];
int sL[1002][1002];
int sU[1002][1002];
int sD[1002][1002];

void solve() {
    memset(sR, 0, sizeof(sR));
    memset(sL, 0, sizeof(sL));
    memset(sU, 0, sizeof(sU));
    memset(sD, 0, sizeof(sD));
    ll ans = 0;
    cin >> R >> C;
    for (int r = 1; r <= R; r++) {
        for (int c = 1; c <= C; c++) {
            cin >> A[r][c];
        }
    }

    for (int r = 1; r <= R; r++) {
        for (int c = C; c > 0; c--) {
            if (A[r][c]) sR[r][c] = sR[r][c + 1] + 1;
        }
    }
    for (int r = 1; r <= R; r++) {
        for (int c = 1; c <= C; c++) {
            if (A[r][c]) sL[r][c] = sL[r][c - 1] + 1;
        }
    }
    for (int c = 1; c <= C; c++) {
        for (int r = R; r > 0; r--) {
            if (A[r][c]) sD[r][c] = sD[r + 1][c] + 1;
        }
    }
    for (int c = 1; c <= C; c++) {
        for (int r = 1; r <= R; r++) {
            if (A[r][c]) sU[r][c] = sU[r - 1][c] + 1;
        }
    }

    for (int r = 1; r <= R; r++) {
        for (int c = 1; c <= C; c++) {
            ans += max(min(sU[r][c] / 2, sR[r][c]) - 1, 0);
            ans += max(min(sU[r][c], sR[r][c] / 2) - 1, 0);
            ans += max(min(sR[r][c] / 2, sD[r][c]) - 1, 0);
            ans += max(min(sR[r][c], sD[r][c] / 2) - 1, 0);
            ans += max(min(sD[r][c] / 2, sL[r][c]) - 1, 0);
            ans += max(min(sD[r][c], sL[r][c] / 2) - 1, 0);
            ans += max(min(sL[r][c] / 2, sU[r][c]) - 1, 0);
            ans += max(min(sL[r][c], sU[r][c] / 2) - 1, 0);
        }
    }

    cout << ans << '\n';
}

int T;

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);

    cin >> T;
    for (int t = 1; t <= T; t++) {
        cout << "Case #" << t << ": ";
        solve();
    }
}

 

BOJ Random Defense #11

728x90

'BOJ' 카테고리의 다른 글

[BOJ 26654 // C++] 원점  (0) 2024.06.03
[BOJ 1635 // C++] 1 또는 -1  (0) 2024.06.02
[BOJ 9911 // C++] ERP  (0) 2024.05.31
[BOJ 1727 // C++] 커플 만들기  (0) 2024.05.30
[BOJ 22887 // C++] Reversort Engineering  (0) 2024.05.29

+ Recent posts