BOJ

[백준 16918번 / java] 봄버맨

syj0522 2024. 7. 9. 04:40

문제

16918번: 봄버맨 (acmicpc.net)

  1. 폭탄은 3초 후 폭발 → 빈칸이 됨 (인접 4칸 포함)
  2. 폭탄도 함께 파괴되어 연쇄 폭발 반응 없음
  3. N초 후 격자의 상태 출력하기

풀이

0초: 폭탄설치

1초: -

2초: 폭탄 없는 모든 칸에 폭탄 설치

3초: 0초에 설치한 것 폭발

4초: 폭탄 없는 모든 칸에 폭탄 설치

5초: 2초에 설치한 것 폭발

6초: 폭탄 없는 모든 칸에 폭탄 설치

...

 

1. timeNow를 0부터 1초씩 증가시키면서 짝수인 경우, 홀수인 경우 나눠 진행한다.

2. timeNow가 N이 되면 현재까지 진행된 상태 출력

3. 폭탄이 3초 후에 터져야 하므로 같은 크기의 격자판을 하나 더 만들어 해당 좌표에 심어진 폭탄의 시간을 관리한다.

 

설치(plant()) : "."을 "O"로 바꾸는 작업. 심은 자리의 시간을 0초로 설정해준다.

폭발(explode()) : 3초가 된 폭탄 + 인접 4자리를 "."로 바꾸는 작업. 격자의 값을 그때그때 바꾸며 탐색을 진행하면 인접 4곳을 터트릴 때 다음에 폭발되어야 할 폭탄이 함께 지워질 수 있기 때문에 임시 행렬에 원본을 복사해두고 그것을 참고하며 진행. 

-> 임시 행렬을 만들지 않고 진행하는 방법 : 인접 4곳을 터트릴 때, 폭탄이 있는 곳 제외하기

 

코드

import java.io.*;
import java.util.*;

public class Main {
    static int R, C, N;
    static String[][] board;
    static int[][] sec;
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer st;

        st = new StringTokenizer(br.readLine());
        R = Integer.parseInt(st.nextToken());
        C = Integer.parseInt(st.nextToken());
        N = Integer.parseInt(st.nextToken());

        board = new String[R][C];
        sec = new int[R][C];
        for(int[] row: sec){
            Arrays.fill(row, -1);
        }
        for(int i=0; i<R; i++){
            String str = br.readLine();
            for(int j=0; j<C; j++){
                board[i][j] = String.valueOf(str.charAt(j));
                sec[i][j] = 0;
            }
        }
        solve(N);
    }
    //1초 후: 입력받은 값 그대로 출력
    //2초 후: 폭탄 없는 칸에 설치
    //3초 후: 0초에 심은 것 + 인접 4칸 폭발
    //4초 후: 폭탄 없는 칸에 설치
    //5초 후: 2초에 심은 것 + 인접 4칸 폭발

    static void solve(int N){
        int timeNow = 0;
        while(true){
            if(timeNow == N){
                print(board);
                break;
            }
            timeNow++;
            increaseTime();

            if(timeNow%2 == 0){
                plant();
            }else if(timeNow > 1){
                explode();
            }
        }
    }
    static void explode(){
        String[][] cpyboard = new String[R][C];
        int[][] cpysec = new int[R][C];
        cpyboard = deepCopy(board);
        cpysec = deepCopy(sec);

        //3초가 된 폭탄 좌표 + 인접 좌표 O으로 만들기
        for(int i=0; i<R; i++){
            for(int j=0; j<C; j++){
                if(cpyboard[i][j].equals("O") && cpysec[i][j] == 3){
                    adj(i, j);
                }
            }
        }
    }
    static void adj(int x, int y){
        //board의 x, y에 .을 삽입
        board[x][y] = ".";
        sec[x][y] = -1;
        //board의 x, y의 인접 좌표에 .을 삽입
        int[] dx = {0, 0, 1, -1};
        int[] dy = {1, -1, 0, 0};

        for(int i=0; i<4; i++){
            int nx = x + dx[i];
            int ny = y + dy[i];
            if(nx<0 || nx>=R || ny<0 || ny>=C)
                continue;
            board[nx][ny] = ".";
            sec[nx][ny] = -1;
        }
    }
    static void plant(){
        //폭탄이 없는 곳에 폭탄 심기
        for(int i=0; i<R; i++){
            for(int j=0; j<C; j++){
                if(board[i][j].equals(".")){
                    board[i][j] = "O";
                    sec[i][j] = 0;
                }
            }
        }
    }
    static void increaseTime(){
        for(int i=0; i<R; i++){
            for(int j=0; j<C; j++){
                if(sec[i][j] != -1)
                    sec[i][j]++;
            }
    }
}
    static void print(String[][] arr){
        for(String[] tmp1: arr){
            for(String tmp2: tmp1){
                System.out.print(tmp2);
            }
            System.out.println();
        }
    }

    static String[][] deepCopy(String[][] arr){
        String[][] result = new String[arr.length][arr[0].length];
        for (int i=0; i<arr.length; i++) {
            result[i] = arr[i].clone();
        }
        return result;
    }
    static int[][] deepCopy(int[][] arr){
        int[][] result = new int[arr.length][arr[0].length];
        for (int i=0; i<arr.length; i++) {
            result[i] = arr[i].clone();
        }
        return result;
    }


}

 

'BOJ' 카테고리의 다른 글

[백준 14890번 / java] 경사로  (0) 2024.07.10
[백준 20152번 / java] Game Addiction  (0) 2024.07.10
[백준 1263번 / java] 시간 관리  (0) 2024.07.09
[백준 20922번 / java] 겹치는 건 싫어  (0) 2024.07.09
[백준 14502 / java] 연구소  (0) 2024.07.09