[BOJ] 4963. 섬의 개수 - DFS

Problem

제출일 : 2020-02-13

문제 풀이 시간 : 20M

난이도 : ★


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

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

img

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

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

input

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

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

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

Output

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

Example

input

1 1
0
2 2
0 1
1 0
3 2
1 1 1
1 1 1
5 4
1 0 1 0 0
1 0 0 0 0
1 0 1 0 1
1 0 0 1 0
5 4
1 1 1 0 1
1 0 1 0 1
1 0 1 0 1
1 0 1 1 1
5 5
1 0 1 0 1
0 0 0 0 0
1 0 1 0 1
0 0 0 0 0
1 0 1 0 1
0 0

output

0
1
1
3
1
9

Solution & Inpression

기본적인 DFS/BFS문제로 DFS나 BFS어떤 풀이를 사용하더라도 문제는 해결할 수 있다.

어렵거나 문제가 이해가 되지 않았던 부분이 없었기 때문에 쉽게 풀 수 있었다

단지 높이와 너비를 입력으로 주는 순서나 0 0이 종료조건이며 대각선 방향도 연결이 되있다는것을 파악하면 한번에 해결할 수 있을 것이라 생각한다.

Code

언어 : JAVA

메모리 : 32,616 kb

실행시간 : 312 ms

import java.io.FileInputStream;
import java.util.Scanner;

public class Main {
    static int W, H, ans;
    static int[][] map;
    // 상, 하, 좌, 우, 좌상, 좌하, 우상, 우하
    static int[] dr = { -1, 1, 0, 0, -1, 1, -1, 1 };
    static int[] dc = { 0, 0, -1, 1, -1, -1, 1, 1 };

    public static void main(String[] args) throws Exception {
        System.setIn(new FileInputStream("res/input.txt"));
        Scanner sc = new Scanner(System.in);

        while (true) {
            W = sc.nextInt();
            if (W == 0)
                break;
            H = sc.nextInt();

            map = new int[H][W];

            for (int i = 0; i < H; i++) {
                for (int j = 0; j < W; j++) {
                    map[i][j] = sc.nextInt();
                }
            }
            ans = 0;
            for (int i = 0; i < H; i++) {
                for (int j = 0; j < W; j++) {
                    if (map[i][j] == 1) {
                        DFS(i, j);
                        ans++;

                    }
                }
            }
            System.out.println(ans);
        } // end of while

    }

    private static void DFS(int i, int j) {
        for (int dir = 0; dir < dc.length; dir++) {
            int nr = i + dr[dir];
            int nc = j + dc[dir];
            if (isRange(nr, nc) && map[nr][nc] == 1) {
                map[nr][nc] = 0;
                DFS(nr, nc);
            }
        }
    }

    private static boolean isRange(int nr, int nc) {
        if (0 <= nr && nr < H && 0 <= nc && nc < W)
            return true;
        return false;
    }
}