ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [1113] 수영장 만들기
    BOJ 2022. 1. 23. 09:31

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

     

    1113번: 수영장 만들기

    지민이는 수영장을 만들려고 한다. 수영장을 만들 곳의 크기는 N*M이고, 각 칸은 직육면체이다. 따라서, 각 칸의 직육면체의 높이가 쓰여 있는 다음과 같은 땅을 생각할 수 있다. 16661 61116 16661 이

    www.acmicpc.net

    <문제>

    뭔가 특이하고 복잡한 문제인거 같지만, H=벽의 높이일때 O(HNM)으로 풀리는 문제다.

    풀이의 방향을 잘 잡으면 정말 쉽게풀 수 있지만, 그렇지 않으면 한참을 헤메기 좋은 문제인듯 싶다.

     

    물을 한칸씩 채워넣는다고 생각할때,

    bfs에서 가장자리(첫행or첫열or마지막행or마지막열)를 방문하면 그곳에는 물이 쌓일 수 없다.

    만약 그러한 경우가 발생하지 않았다면, 기존에 방문한 정점을 다시한번 순회하며 물을 채워넣어준다.

    채워넣은 만큼 정답을 업데이트 해주고, 해당 정점의 a[i][j]를 높이로 만들어주면

    다음 높이를 탐색할때 중복으로 물의 양을 계산하는것을 방지할 수 있다.

     

    <소스코드>

    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
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    #include <bits/stdc++.h>
    using namespace std;
    using pi = pair<intint>;
    typedef struct {
        int y, x;
    } state;
    int n, m, ans, dy[4= {010-1}, dx[4= {10-10};
    int a[55][55];
    bool vst[55][55];
    void f(int sy, int sx, int h) {
        memset(vst, 0sizeof(vst));
        queue<state> q;
        q.push({sy, sx});
        vst[sy][sx] = true;
        vector<pi> v;
        v.clear();
        v.push_back({sy, sx});
        while (!q.empty()) {
            state cur = q.front();
            q.pop();
            if (cur.y == 0 || cur.x == 0 || cur.y == n - 1 || cur.x == m - 1) {
                return;
            }
            for (int i = 0; i < 4; i++) {
                int y = cur.y + dy[i];
                int x = cur.x + dx[i];
                if (a[y][x] <= a[sy][sx] && vst[y][x] == false) {
                    vst[y][x] = true;
                    q.push({y, x});
                    v.push_back({y, x});
                }
            }
        }
        for (auto i : v) {
            ans += (h - a[i.first][i.second]);
            a[i.first][i.second] = h;
        }
        return;
    }
    int main(void) {
        ios_base::sync_with_stdio(0);
        cin.tie(0);
        cin >> n >> m;
        int i, j;
        char in[55][55];
        for (i = 0; i < n; i++)
            for (j = 0; j < m; j++) {
                cin >> in[i][j];
                a[i][j] = in[i][j] - '0';
            }
        for (int len = 2; len <= 9; len++) {
            memset(vst, 0sizeof(vst));
            for (i = 0; i < n; i++) {
                for (j = 0; j < m; j++) {
                    if (i == 0 || j == 0 || i == n - 1 || j == m - 1continue;
                    if (a[i][j] < len) {
                        f(i, j, len);
                    }
                }
            }
        }
        cout << ans;
        return 0;
    }
    cs

     

     

    'BOJ' 카테고리의 다른 글

    [4375] 1  (0) 2022.01.26
    [17471] 게리맨더링  (0) 2022.01.25
    [3687]성냥개비  (0) 2022.01.23
    [20057] 마법사 상어와 토네이도  (0) 2022.01.23
    [16208] 귀찮음  (0) 2022.01.17

    댓글