백준 알고리즘 4963번 : 섬의 개수

Zoo Da·2021년 6월 24일
0

백준 알고리즘

목록 보기
85/337
post-thumbnail

링크

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

문제

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

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

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

입력

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

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

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

출력

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

예제 입력 및 출력

풀이법

  1. 1 은 땅, 0은 바다라고 하였음으로 모든 방문배열과 그래프(인접 행렬)방식은 전부 0으로 초기화를 한다.
  2. 한번 수행을 하고 그래프와 방문 배열을 초기화해 주기 위한 clear함수를 작성했다.
  3. DFS의 FloodFill방식을 이용해서 풀었다 문제에서 상,하,좌,우,대각선까지 포함한다고 하였음으로 dx와 dy배열을 선언해서 현재 좌표에서 상,하,좌,우,대각선을 접근할 수 있는지 판단하고 만약 방문하지 않았고, 땅이라면(1이라면) dfs를 호출해서 탐색을 한다.
  4. 위의 문제에서 섬의 개수를 물어보았기 때문에 2차원 배열을 전부 돌면서 방문하지 않았고 섬이라면 DFS탐색을 시작할 때 count변수를 1증가시키고 count변수를 출력한다.
  5. count변수의 값을 출력한 후에는 아까 정의했던 clear함수를 호출하여 2차원 인접 행렬 방식의 그래프와 visited배열을 초기화 해주어야 다음에 들어오는 입력 값에 대한 수행을 원할히 할 수 있다.

풀이 코드(C언어)

// 4963번 : 섬의 개수

#include <stdio.h>
#include <stdlib.h>
#define MAX 51
// 1 : 땅, 0 : 바다
int visited[MAX][MAX] = {
    0,
};
int graph[MAX][MAX] = {
    0,
};

int dx[] = {-1, 0, 1, 0, 1, 1, -1, -1};
int dy[] = {0, -1, 0, 1, 1, -1, 1, -1};

void clear()
{
    for (int i = 0; i < MAX; i++)
    {
        for (int j = 0; j < MAX; j++)
        {
            graph[i][j] = 0;
            visited[i][j] = 0;
        }
    }
}

void dfs(int x, int y)
{
    visited[x][y] = 1;
    //graph[x][y] = 0;
    if (graph[x][y] == 0)
        return;
    int newX, newY;
    for (int i = 0; i < 8; i++)
    {
        newX = x + dx[i];
        newY = y + dy[i];
        if (0 < newX && newX < MAX && 0 < newY && newY < MAX)
        {
            if (visited[newX][newY] == 0 && graph[newX][newY] == 1)
            {
                dfs(newX, newY);
            }
        }
    }
}

int main()
{
    while (1)
    {
        int w, h;
        int count = 0;
        scanf("%d%d", &w, &h);
        if (w == 0 && h == 0)
            break;
        for (int i = 1; i <= h; i++)
        {
            for (int j = 1; j <= w; j++)
            {
                scanf("%d", &graph[i][j]);
            }
        }
        for (int i = 1; i <= h; i++)
        {
            for (int j = 1; j <= w; j++)
            {
                if (visited[i][j] == 0 && graph[i][j] == 1)
                {
                    dfs(i, j);
                    count++;
                }
            }
        }
        printf("%d\n", count);
        clear();
    }
    return 0;
}
profile
메모장 겸 블로그

0개의 댓글