공부방

dfs문제 본문

문법/알고리즘

dfs문제

코딩 화이팅 2023. 3. 28. 23:21

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

 

4963번: 섬의 개수

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

www.acmicpc.net

package DFS_BFS;

import java.util.Scanner;

public class 섬의개수_4963 {
    static int w, h; // 지도의 너비와 높이
    static int[][] map; // 지도를 나타내는 인접 행렬
    static boolean[][] visited; // 방문 여부를 나타내는 배열
    static int[] dy = {-1, 0, 1, -1, 1, -1, 0, 1}; // y 좌표 이동
    static int[] dx = {-1, -1, -1, 0, 0, 1, 1, 1}; // x 좌표 이동
    //대각위왼,왼,대각아래왼,위,아래,대각위오른,오른,대각아래오른

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (true) {
            w = sc.nextInt(); // 지도의 너비 입력
            h = sc.nextInt(); // 지도의 높이 입력
            if (w == 0 && h == 0) {
                break; // 너비와 높이가 0인 경우 종료
            }

            map = new int[h][w];
            visited = new boolean[h][w];

            // 지도 입력 받기
            for (int i = 0; i < h; i++) {
                for (int j = 0; j < w; j++) {
                    map[i][j] = sc.nextInt();
                }
            }

            int count = 0; // 섬의 개수를 저장할 변수
            // 전체 지도를 순회하면서 섬을 찾음
            for (int i = 0; i < h; i++) {
                for (int j = 0; j < w; j++) {
                    if (map[i][j] == 1 && !visited[i][j]) {
                        dfs(i, j); // 섬을 찾으면 DFS 탐색 실행
                        count++; // 섬의 개수 증가
                    }
                }
            }
            System.out.println(count); // 섬의 개수 출력
        }
    }

    // DFS 탐색 메소드
    public static void dfs(int x, int y) {
        visited[x][y] = true; // 현재 위치를 방문 처리

        // 상, 하, 좌, 우, 대각선 방향으로 이동
        for (int i = 0; i < 8; i++) {
            int nx = x + dx[i];
            int ny = y + dy[i];

            // 이동한 위치가 지도 내에 있고
            if (nx >= 0 && ny >= 0 && nx < h && ny < w) {
                // 이동한 위치가 섬이면서 아직 방문하지 않았다면
                if (map[nx][ny] == 1 && !visited[nx][ny]) {
                    dfs(nx, ny); // 이동한 위치에서 다시 DFS 탐색 실행
                }
            }
        }
    }
}

첫 dfs문제라 dfs에 대해 이해는 했지만 어떻게 대입해야될지 몰랐다. dfs는 완전탐색 중 백트래킹의 방법 중 하나로 말 그대로 다 돌아보며 확인하는 것이다. 위 같은 문제는 0,0부터 인접 행렬을 사용하여 8방 탐색을 하며 만약 섬이 있다면 그 섬으로 이동하여 다시 8방 탐색을 하며 dfs를 통한 깊이 우선 탐색을 하는 문제이다. 그래서 8방 탐색을 하며 완전 탐색을 하고 더이상 섬이 없다면 이제 다음 인덱스를 가며 또 8방 탐색을 하며 dfs탐색을 하는 문제이다. 어떻게 푸는지 첫 dfs문제라 어려웠지만 그래도 감은 어느정도 잡힌 것 같다. 다음에는 bfs로도 풀어봐야겠다.

결론 : 8방 탐색을 하는 방법/8방 탐색을 하며 dfs를 통한 완전 탐색 백트래킹.

'문법 > 알고리즘' 카테고리의 다른 글

bfs문제  (0) 2023.04.05
find,union  (0) 2023.03.29
n과 m(9)  (0) 2023.03.25
TreeSet구현 문제  (0) 2023.03.20
방향벡터, 돌아서 다시 처음으로(순회)  (0) 2023.03.06