본문 바로가기

Algorithm/Baekjoon

[ 백준 - Java ] 섬의 개수 ( 자바 )

728x90

( dfs / 섬의 개수 / 4963 )

[문제]

문제 설명

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

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

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

제한사항

메모리 제한 : 128 MB

입출력 예시

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

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

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

 

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


[코드]

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class LandCount4963 {
    static int[][] map;             // 섬 정보가 있는 2차원 배열
    static List<Integer> answer;    // 정답을 담을 배열
    // 12시 방향부터 시계방향으로 이동할 x, y의 값 차이
    static final int[] dx = {0, 1, 1, 1, 0, -1, -1, -1};
    static final int[] dy = {-1, -1, 0, 1, 1, 1, 0, -1};

    public static void main(String[] args){
        // === 입력 ===
        Scanner sc = new Scanner(System.in);
        answer = new ArrayList<>();             // 정답배열 초기화

        while(true){
            // 가로세로 크기 입력
            int w = sc.nextInt();
            int h = sc.nextInt();
            // 만일 둘다 0일경우 문제 종료
            if(w == 0 && h == 0) break;
            // 현재 입력받은 크기로 map초기화
            map = new int[h][w];
            // map정보 입력
            for(int i = 0; i < h; i++){
                for(int j = 0; j < w; j++){
                    map[i][j] = sc.nextInt();
                }
            }

            // === 구현 ===
            int cnt = 0;        // 몇개의 섬이있는지 카운트할 변수
            // map의 전체 탐색
            for(int i = 0; i < h; i++){
                for(int j = 0; j < w; j++){
                    // 만일 방문하지 않았거나, 섬이 있는 경우 깊이우선 탐색
                    if(map[i][j] != 0){
                        dfs(j, i, w, h);
                        cnt++;
                    }
                }
            }
            answer.add(cnt);        // 정답 추가
        }

        sc.close();

        // === 출력 ===
        for(int i : answer) System.out.println(i);
    }
    // 깊이우선탐색
    public static void dfs(int x, int y, int w, int h){
        if(map[y][x] == 0) return;  // 현재 위치에 섬이 없거나 이미 방문한 경우 return
        // 현재위치 0으로 처리함으로 방문여부 처리
        map[y][x] = 0;
        // 8개의 방향 체크
        for(int i = 0; i < 8; i++){
            int nx = x + dx[i];
            int ny = y + dy[i];

            // 다음 방향이 map을 넘지 않으면서 섬이 존재하거나 아직 방문하지 않은경우
            if(nx >= 0 && nx < w && ny >= 0 && ny < h && map[ny][nx] != 0){
                dfs(nx, ny, w, h);      // 깊이우선탐색
            }
        }
    }
}

문제 링크

 

4963번: 섬의 개수

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

www.acmicpc.net

제가 잘못 알고 있거나 잘못된 부분이 있을 경우 알려주시고 추가로 궁금한 점 있으신 분들도 댓글이나 메일 주시면 성실히 답변해 드리겠습니다.🧑🏻‍💻

감사합니다~😄

728x90