치춘짱베리굿나이스

[백준] 4963 본문

카테고리 없음

[백준] 4963

치춘 2023. 9. 11. 22:32

섬의 개수

문제

정사각형으로 이루어져 있는 섬과 바다 지도가 주어진다. 섬의 개수를 세는 프로그램을 작성하시오.

한 정사각형과 가로, 세로 또는 대각선으로 연결되어 있는 사각형은 걸어갈 수 있는 사각형이다.

두 정사각형이 같은 섬에 있으려면, 한 정사각형에서 다른 정사각형으로 걸어서 갈 수 있는 경로가 있어야 한다. 지도는 바다로 둘러싸여 있으며, 지도 밖으로 나갈 수 없다.

입력

입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 테스트 케이스의 첫째 줄에는 지도의 너비 w와 높이 h가 주어진다. w와 h는 50보다 작거나 같은 양의 정수이다.

둘째 줄부터 h개 줄에는 지도가 주어진다. 1은 땅, 0은 바다이다.

입력의 마지막 줄에는 0이 두 개 주어진다.

출력

각 테스트 케이스에 대해서, 섬의 개수를 출력한다.

풀이

#include <iostream>
#include <queue>

int dir[2][8] = {{-1, -1, 0, 1, 1, 1, 0, -1}, {0, 1, 1, 1, 0, -1, -1, -1}};
int map[51][51];
bool visited[51][51];
std::queue<std::pair<int, int> > que;

void initialize_visited(int n, int m) {
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            visited[i][j] = false;
        }
    }
}

int bfs_inner(int n, int m, int startX, int startY) {
    que.push(std::make_pair(startY, startX));
    visited[startY][startX] = true;

    while (!que.empty()) {
        int currentY = que.front().first;
        int currentX = que.front().second;
        que.pop();

        for (int i = 0; i < 8; i++) {
            int coordY = currentY + dir[0][i];
            int coordX = currentX + dir[1][i];
            if (coordX < 0 || coordX >= n || coordY < 0 || coordY >= m)
                continue;
            if (visited[coordY][coordX] || map[coordY][coordX] == 0)
                continue;
            que.push(std::make_pair(coordY, coordX));
            visited[coordY][coordX] = true;
        }
    }

    return 1;
}

int bfs(int n, int m) {
    int cnt = 0;
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            if (!visited[i][j] && map[i][j] == 1)
                cnt += bfs_inner(n, m, j, i);
        }
    }
    return cnt;
}

int main(void) {
    int n, m;

    while (true) {
        std::cin >> n >> m;
        if (n == 0 && m == 0) return 0;
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                std::cin >> map[i][j];
            }
        }
        initialize_visited(n, m);
        std::cout << bfs(n, m) << "\n";
    }
}

반성회

visited[coordY][coordX] = true;

visited[currentY][currentX] = true;

메모리 초과가 계속 나서 왜지 했는데 윗 줄을 아랫 줄로 적어서 틀렸던것이었다

좌표를 coord 쓰는 시점에서 current 좌표를 넣어버려서 visited 체크가 제대로 안된 바람에 큐에 중복된 좌표가 미친듯이 들어가는 대참사가 발생해서 메모리 초과가 발생했던 것

같이 찾아주신 모님 감사합니다..

Comments