• [BOJ] 14502번 연구소 Java 풀이

    2021. 6. 19.

    by. SDev

    728x90

     

     

    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.util.Arrays;
    import java.util.LinkedList;
    import java.util.Queue;
    import java.util.StringTokenizer;
    public class Main {
    static int N, M, answer;
    static int[][] board;
    static int[] dx = {0, 0, 1, -1};
    static int[] dy = {1, -1, 0, 0};
    public static void main(String[] args) throws Exception{
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    StringTokenizer st = new StringTokenizer(br.readLine());
    N = Integer.parseInt(st.nextToken());
    M = Integer.parseInt(st.nextToken());
    board = new int[N][M];
    for(int i = 0; i < N; i++) {
    st = new StringTokenizer(br.readLine());
    for(int j = 0; j < M; j++) {
    board[i][j] = Integer.parseInt(st.nextToken());
    }
    }
    dfs(0);
    System.out.println(answer);
    }
    // dfs로 벽 세우기
    public static void dfs(int cnt) {
    // 벽이 모두 세워졌으면 바이러스 전파하고, 가능하면 결과 갱신
    if(cnt == 3) {
    bfs();
    }else { // 벽이 모두 세워지지 않았으면 세워질 때까지 세움
    for(int i = 0; i < N; i++) {
    for(int j = 0; j < M; j++) {
    // 빈칸이면
    if(board[i][j] == 0) {
    // 벽 세우기
    board[i][j] = 1;
    dfs(cnt + 1);
    // 다음 탐색을 위해 벽 허물기
    board[i][j] = 0;
    }
    }
    }
    }
    }
    // bfs로 바이러스 전파
    public static void bfs() {
    Queue<Virus> q = new LinkedList<>();
    // 수행 시점에 board 정보 복사
    int[][] tempBoard = new int[N][M];
    for(int i = 0; i < N; i++) {
    for(int j = 0; j < M; j++) {
    tempBoard[i][j] = board[i][j];
    }
    }
    // 초기 바이러스 위치를 큐에 저장
    for(int i = 0; i < N; i++) {
    for(int j = 0; j < M; j++) {
    if(tempBoard[i][j] == 2) {
    q.add(new Virus(i, j));
    }
    }
    }
    // 바이러스 전파
    while(!q.isEmpty()) {
    Virus now = q.poll();
    // 4방향 이동
    for(int d = 0; d < 4; d++) {
    int nx = now.row + dx[d];
    int ny = now.col + dy[d];
    // board를 벗어나면 이동 불가
    if(nx < 0 || nx >= N || ny < 0 || ny >= M) continue;
    // 빈공간이면
    if(tempBoard[nx][ny] == 0) {
    // 다음 위치에 바이러스 감염 후 이동
    tempBoard[nx][ny] = 2;
    q.add(new Virus(nx, ny));
    }
    }
    } // end of 바이러스 전파
    calSafeRegion(tempBoard);
    }
    // 현재 상태의 안전 영역을 계산하고, 현재 answer보다 크면 업데이트
    public static void calSafeRegion(int[][] tempBoard) {
    int cnt = 0;
    for(int i = 0; i < N; i++) {
    for(int j = 0; j < M; j++) {
    if(tempBoard[i][j] == 0) cnt++;
    }
    }
    if(answer < cnt) {
    answer = cnt;
    }
    }
    }
    class Virus{
    int row, col;
    public Virus(int row, int col) {
    this.row = row;
    this.col = col;
    }
    }

    댓글