Algorithm

[Algorithm] 연구소

씬프 2021. 6. 10. 15:54
반응형

풀이

 

벽을 세운 개수가 3개가 될 때마다 임시 맵에 바이러스가 퍼진 결과, 그리고 안전한 공간을 계산하도록 한다.

안전한 공간의 수는 최대값으로 갱신한다.

바이러스가 퍼지는 공간은 DFS로 면적을 포함해가면 된다.

    public static void virus(int x, int y) {
        for (int i = 0; i < 4; i++) {
            int nx = x + dx[i];
            int ny = y + dy[i];
            if (0 <= nx && nx < n && 0 <= ny && ny < m) {
                if (tmp[nx][ny] == 0) {
                    tmp[nx][ny] = 2;
                    virus(nx, ny);
                }
            }
        }
    }

안전한 공간은 바이러스가 퍼지고 난 후에 맵에서 안전한 공간의 갯수를 파악한다.

    public static int getSafe() {
        int safe = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (tmp[i][j] == 0) {
                    safe++;
                }
            }
        }
        return safe;
    }

벽을 세우는 방식은 재귀 호출을 통해 맵에서 모든 경우의 수를 세워볼 수 있도록 한다.

처음에 0,0 0,1 0,2 -> 0,0 0,1 0,3 -> ... -> 0,0 0,1 n,m -> 0,0 0,2 0,3 -> ...

이렇게 모든 경우를 확인할 수 있다. 그 때 벽의 개수가 3개일 때마다 바이러스의 퍼짐 정도와 안전한 공간을 계산하면 된다.

    public static void dfs(int cnt) {
        // 벽 3개 건설된 경우
        if (cnt == 3) {
            // 바이러스 퍼짐 정도와 안전공간 개수 확인
        }
        // 벽 건설
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (map[i][j] == 0) {
                    map[i][j] = 1;
                    cnt++;
                    dfs(cnt);
                    map[i][j] = 0;
                    cnt--;
                }
            }
        }
    }

전체 소스코드

import java.util.*;

public class Main {
    public static int n, m;
    public static int[][] map = new int[8][8];
    // 바이러스 전파 상황 저장할 맵
    public static int[][] tmp = new int[8][8];
    
    public static int safeZone = 0;
    
    // 상 좌 하 우
    public static int[] dx = {-1, 0, 1, 0};
    public static int[] dy = {0, -1, 0, 1};

    public static void virus(int x, int y) {
        for (int i = 0; i < 4; i++) {
            int nx = x + dx[i];
            int ny = y + dy[i];
            if (0 <= nx && nx < n && 0 <= ny && ny < m) {
                if (tmp[nx][ny] == 0) {
                    tmp[nx][ny] = 2;
                    virus(nx, ny);
                }
            }
        }
    }

    public static int getSafe() {
        int safe = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (tmp[i][j] == 0) {
                    safe++;
                }
            }
        }
        return safe;
    }

    public static void dfs(int cnt) {
        // 벽 3개 건설된 경우
        if (cnt == 3) {
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    tmp[i][j] = map[i][j];
                }
            }
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    if (tmp[i][j] == 2) {
                        virus(i, j);
                    }
                }
            }
            safeZone = Math.max(safeZone, getSafe());
            return;
        }
        // 벽 건설
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (map[i][j] == 0) {
                    map[i][j] = 1;
                    cnt++;
                    dfs(cnt);
                    map[i][j] = 0;
                    cnt--;
                }
            }
        }
    }

    public static void main(String[] args) {
        
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        m = sc.nextInt();

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                map[i][j] = sc.nextInt();
            }
        }
        sc.close();

        dfs(0);

        System.out.println(safeZone);

    } // end main method
}

'Algorithm' 카테고리의 다른 글

[Algorithm] 경쟁적 전염  (0) 2021.06.11
[Algorithm] 최장 증가 부분 수열 (LIS)  (0) 2021.06.10
[Algorithm] 특정 거리의 도시 찾기  (0) 2021.06.09
[Algorithm] 치킨 배달  (0) 2021.06.08
[Algorithm] 기둥과 보 설치  (0) 2021.06.07