Algorithm

연구소 - '이것이 코딩 테스트다 with 파이썬'

태인킴 2020. 9. 1. 18:49
반응형
 

이것이 취업을 위한 코딩 테스트다 with 파이썬

IT 취준생이라면 누구나 입사하고 싶은 카카오ㆍ삼성전자ㆍ네이버ㆍ라인!취업의 성공 열쇠는 알고리즘 인터뷰에 있다!IT 취준생이라면 누구나 가고 싶어 하는 카카오, 라인, 삼성전자의 2016년부

book.naver.com

'연구소' 문제는 0은 안전 지역, 1은 벽, 2는 바이러스로 되어있는 n x m의 맵이 있습니다. 바이러스는 좌/우/상/하 로 전파 합니다. 이때 벽을 3곳만 설치 할수 있을때 안전지역 칸의 최대값을 출력 하는 문제 입니다.

 

1. 접근

1. 3칸의 벽을 모든 경우의 수 만큼 벽을 치고

2. 바이러스가 상/하/좌/우 로 전파 합니다.

3. 이때 안전 지역의 최대값을 출력 한다.

 

2중 반복문으로 3칸의 모든 경우의수를 벽을 치면서, 바이러스의 현재 위치부터 바이러스 전파를 시킵니다. 이때 BFS/DFS로 전파를 시킬수 있습니다. 전파가 끝난후 안전지역의 최대값을 출력 합니다. n, m의 최대값이 8까지 밖에 될수 없으므로, 벽 3칸으로 치는 모든 경우의수를 탐색하는데는 문제가 없습니다.

 

import java.util.*;

public class Page341 {

    public static int n, m, result = 0;
    public static int[][] arr = new int[8][8]; // 초기 맵 배열
    public static int[][] temp = new int[8][8]; // 벽을 설치한 뒤의 맵 배열

    // 4가지 이동 방향에 대한 배열
    public static int[] dx = {-1, 0, 1, 0};
    public static int[] dy = {0, 1, 0, -1};

    // 4 6
    // 0 0 0 0 0 0
    // 1 0 0 0 0 2
    // 1 1 1 0 0 2
    // 0 0 0 0 0 2
    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++) {
                arr[i][j] = sc.nextInt();
            }
        }

        dfs(0);
        System.out.println(result);
    }

    // 깊이 우선 탐색(DFS)을 이용해 울타리를 설치하면서, 매 번 안전 영역의 크기 계산
    public static void dfs(int count) {
        // 울타리가 3개 설치된 경우
        if (count == 3) {
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    temp[i][j] = arr[i][j];
                }
            }
            // 각 바이러스의 위치에서 전파 진행
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    if (temp[i][j] == 2) {
                        virus(i, j);
                    }
                }
            }
            // 안전 영역의 최대값 계산
            result = Math.max(result, getScore());
            return;
        }
        // 빈 공간에 울타리를 설치
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (arr[i][j] == 0) {
                    arr[i][j] = 1;
                    count += 1;
                    dfs(count);
                    arr[i][j] = 0;
                    count -= 1;
                }
            }
        }
    }

    // 깊이 우선 탐색(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 (nx >= 0 && nx < n && ny >= 0 && ny < m) {
                if (temp[nx][ny] == 0) {
                    // 해당 위치에 바이러스 배치하고, 다시 재귀적으로 수행
                    temp[nx][ny] = 2;
                    virus(nx, ny);
                }
            }
        }
    }

    // 현재 맵에서 안전 영역의 크기 계산하는 메서드
    public static int getScore() {
        int score = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (temp[i][j] == 0) {
                    score += 1;
                }
            }
        }
        return score;
    }
}

 

 

 

 

 

반응형