[백준] 16918: 봄버맨 (Java)

Yoon Uk·2022년 7월 14일
0

알고리즘 - 백준

목록 보기
32/130
post-thumbnail
post-custom-banner

문제

BOJ 16918: 봄버맨 https://www.acmicpc.net/problem/16918

풀이

  • 입력값 그대로 char 배열이 아닌 int 배열을 사용해 해결한다.
  • 폭탄이 없는 자리는 0, 폭탄은 터지는 시간(예를 들어, 3초에 터지면 3)을 배열에 넣는다.
  • 시간(t) 이 증가하도록 반복문을 짠 뒤 반복문 안에 폭탄 세팅(setBomb())폭탄 폭발(explosion())을 구현한다.
    • 폭탄이 터질 때 바로 map 배열에 적용하면 같은 시간에 터져야 할 폭탄이 영향을 받을 수 있어 boolean 배열인 isExplod에 터진 폭탄의 영향을 받는 위치를 true로 바꿔준다.
    • isExplod배열 중 true인 좌표를 map 배열의 좌표에 터지는 시간값을 계산하여 넣어준다.

코드

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

public class Main {
	
	static int R, C, N;
	static char[][] ansMap; // 출력에 사용할 배열
	static int[][] map; // 풀이에 사용할 배열
	static boolean[][] isExplod; // 터진 폭탄에 영향을 받은 위치를 표시할 배열
	static int[] dx = {0, 0, 1, -1};
	static int[] dy = {1, -1, 0, 0};
	
	public static void main(String[] args) throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine(), " ");
		R = Integer.parseInt(st.nextToken());
		C = Integer.parseInt(st.nextToken());
		N = Integer.parseInt(st.nextToken());
		
		map = new int[R][C];
		ansMap = new char[R][C];
		isExplod = new boolean[R][C];
		// 입력 - 현재 시간: 0
		for(int i=0; i<R; i++) {
			String str = br.readLine();
			for(int j=0; j<C; j++) {
				char c = str.charAt(j);
				if(c == '.') {
					map[i][j] = 0;
				} else if(c == 'O') {
                	// 현재 시간이 0이기 때문에 3초가 되는 순간 폭탄이 터진다.
					map[i][j] = 3;
				}
			}
		}
		
		// 2초부터 시작
		for(int t=2; t<=N; t++) {
        	// 폭탄이 터진 흔적(true, false 가 기록된 배열)을 새롭게 초기화 해 준다.
			isExplod = new boolean[R][C];
            // 폭탄을 현재 시간에 맞춰 세팅해 준다.
			setBomb(t);
						
			for(int i=0; i<R; i++) {
				for(int j=0; j<C; j++) {
                	// 배열에 있는 값이 현재 시간과 같다면 현재 폭탄이 터지게 된다.
					if(map[i][j] == t) {
                    	// 모든 폭탄이 동시에 터지기 때문에 폭탄이 터졌을 때 영향을 주는 범위까지만 true로 체크를 해 둔다.
						checkExplod(i, j);
					} 
				}
			}
			// true로 체크된 범위만 배열에 0을 넣어 바꿔준다.
			explosion();			
		}
		
        // 출력 형식에 맞춰 답 출력
		printAnswer();
	}
	// 시간 되면 폭탄 터트리는 메소드
	// true -> 폭탄 터진 자리 -> 터트려서 0으로 바꿔줌
	static void explosion() {
		for(int i=0; i<R; i++) {
			for(int j=0; j<C; j++) {
				if(isExplod[i][j]) {
					map[i][j] = 0;
				}
			}
		}
	}
	
	// 폭탄 세팅 메소드
    // 현재 시간을 입력받아 터지는 시간인 3초를 더한 값을 배열에 넣어준다.
	static void setBomb(int startTime) {
		for(int i=0; i<R; i++) {
			for(int j=0; j<C; j++) {
				if(map[i][j] == 0) {
					map[i][j] = startTime + 3;
				}
			}
		}
	}
	
	// 폭탄이 터져서 영향을 받은 자리를 true로 바꿔준다.
	static void checkExplod(int x, int y) {
		isExplod[x][y] = true;
		
		for(int t=0; t<4; t++) {
			int nx = x + dx[t];
			int ny = y + dy[t];
			
			if(nx < 0 || ny < 0 || nx >= R || ny >= C) continue;
			
			isExplod[nx][ny] = true;
		}
	}
	
    // 숫자로 되어 있는 배열을 출력 형식에 맞춰 출력해주는 메소드
	static void printAnswer() {
		for(int i=0; i<R; i++) {
			for(int j=0; j<C; j++) {
				if(map[i][j] == 0) {
					ansMap[i][j] = '.';
				} else {
					ansMap[i][j] = 'O';
				}
			}
		}
		
		for(int i=0; i<R; i++) {
			for(int j=0; j<C; j++) {
				System.out.print(ansMap[i][j]);
			}
			System.out.println();
		}
	}
	
}

정리

  • 폭탄이 터질 때 바로 map 배열에 적용하면 같은 시간에 터져야 할 폭탄이 영향을 받을 수 있는데 이 부분을 처음에 생각하지 못 해 빠르게 해결하지 못했다.
post-custom-banner

0개의 댓글