문제 링크

  • 내 풀이
#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <queue>
#include <vector>

#define pii pair<int,int>

using namespace std;

constexpr int dr[4] = { -1, 1, 0, 0 }, dc[4] = { 0, 0, -1, 1 };

struct dt {
    int r, c, v;
};

int N, M, m[300][300], ck[300][300];
queue<pii> q;

int cntShore(int r, int c)
{
    int ret = 0;
    for (int d = 0; d < 4; d++)
    {
        int nr = r + dr[d];
        int nc = c + dc[d];

        if (!m[nr][nc])
        {
            ret += 1;
        }
    }

    return ret;
}

int solve()
{
    vector<dt> dtlst;

    int a = 1, ret = 0;
    while (a)
    {
        for (int r = 0; r < N; r++) for (int c = 0; c < M; c++)
            ck[r][c] = 0;

        a = 0;
        for (int r = 1; r < N - 1; r++)
        {
            for (int c = 1; c < M - 1; c++)
            {
                if (!m[r][c] || ck[r][c])
                    continue;

                if (m[r][c] && ck[r][c] == 0 && a)
                    return ret;

                q.push({ r, c });
                ck[r][c] = 1;
                a = 1;

                while (!q.empty())
                {
                    int rr = q.front().first;
                    int cc = q.front().second;

                    dtlst.push_back({ rr, cc, cntShore(rr, cc) });

                    for (int d = 0; d < 4; d++)
                    {
                        int nr = rr + dr[d];
                        int nc = cc + dc[d];

                        if (!m[nr][nc] || ck[nr][nc])
                            continue;
                        q.push({ nr, nc });
                        ck[nr][nc] = 1;

                    }

                    q.pop();
                }

                for (const auto& dt : dtlst)
                {
                    m[dt.r][dt.c] -= dt.v;
                    if (m[dt.r][dt.c] < 0)
                        m[dt.r][dt.c] = 0;
                }

                dtlst.clear();
            }
        }
        ret += 1;
    }

    return 0;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> N >> M;

    for (int r = 0; r < N; r++)
    {
        for (int c = 0; c < M; c++)
        {
            cin >> m[r][c];
        }
    }

    int result = solve();
    cout << result << "\n";
    return 0;
}

빙산의 위치를 찾기 위해 전체를 매번 스캔하여 오버헤드가 발생하였다.

  • 다른 사람 풀이
#include <cstdio>
#include <queue>
#include <vector>
#include <cstring>

using namespace std;

struct Point {
    int x, y;
};

queue<Point> q;
vector<Point> v;
bool visited[310][310] = { 0, };
int graph[310][310] = { 0, };
int dx[4] = { 0, 1, 0, -1 }, dy[4] = { 1, 0, -1, 0 };
int n, m, year = 0, totalGlacier = 0;

int main(void) {
    scanf("%d %d", &n, &m);

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            scanf("%d", &graph[i][j]);
            if (graph[i][j] != 0) v.push_back({ j , i });
        }
    }

    totalGlacier = v.size();

    while (true) {
        // Search a first node for bfs
        for (int i = 0; i < v.size(); i++) {
            if (graph[v[i].y][v[i].x] > 0) {
                q.push(v[i]); visited[v[i].y][v[i].x] = true;
                break;
            }
        }

        // Start bfs
        int cnt = 0, numOfMeltedIce = 0;
        while (!q.empty()) {
            Point cur = q.front(); q.pop();
            int numOfWater = 0;
            cnt++;

            for (int i = 0; i < 4; i++) {
                Point next = { cur.x + dx[i], cur.y + dy[i] };

                if (!visited[next.y][next.x] && graph[next.y][next.x] <= 0) numOfWater++;
                if (!visited[next.y][next.x] && graph[next.y][next.x] > 0) {
                    q.push({ next.x, next.y });
                    visited[next.y][next.x] = true;
                }
            }
            graph[cur.y][cur.x] -= numOfWater;

            if (graph[cur.y][cur.x] <= 0) numOfMeltedIce++;
        }
        memset(visited, 0, sizeof(visited));
        year++;

        if (cnt != totalGlacier) {
            printf("%d", year - 1);
            return 0;
        }

        totalGlacier -= numOfMeltedIce;

        if (totalGlacier == 0) {
            printf("0");
            return 0;
        }
    }
}

먼저 빙상의 위치와 갯수를 미리 저장하여 오버헤드를 줄였다. 본받아야 겠다.

댓글남기기