본문 바로가기

코딩테스트 연습/백준

[ 백준 / 16918 번 ] Silver I 봄버맨 - Solved by java

www.acmicpc.net/problem/16918

 

16918번: 봄버맨

첫째 줄에 R, C, N (1 ≤ R, C, N ≤ 200)이 주어진다. 둘째 줄부터 R개의 줄에 격자판의 초기 상태가 주어진다. 빈 칸은 '.'로, 폭탄은 'O'로 주어진다.

www.acmicpc.net

문제

봄버맨은 크기가 R×C인 직사각형 격자판 위에서 살고 있다. 격자의 각 칸은 비어있거나 폭탄이 들어있다.

폭탄이 있는 칸은 3초가 지난 후에 폭발하고, 폭탄이 폭발한 이후에는 폭탄이 있던 칸이 파괴되어 빈 칸이 되며, 인접한 네 칸도 함께 파괴된다. 즉, 폭탄이 있던 칸이 (i, j)인 경우에 (i+1, j), (i-1, j), (i, j+1), (i, j-1)도 함께 파괴된다. 만약, 폭탄이 폭발했을 때, 인접한 칸에 폭탄이 있는 경우에는 인접한 폭탄은 폭발 없이 파괴된다. 따라서, 연쇄 반응은 없다.

봄버맨은 폭탄에 면역력을 가지고 있어서, 격자판의 모든 칸을 자유롭게 이동할 수 있다. 봄버맨은 다음과 같이 행동한다.

  • 가장 처음에 봄버맨은 일부 칸에 폭탄을 설치해 놓는다. 모든 폭탄이 설치된 시간은 같다.
  • 다음 1초 동안 봄버맨은 아무것도 하지 않는다.
  • 다음 1초 동안 폭탄이 설치되어 있지 않은 모든 칸에 폭탄을 설치한다. 즉, 모든 칸은 폭탄을 가지고 있게 된다. 폭탄은 모두 동시에 설치했다고 가정한다.
  • 1초가 지난 후에 3초 전에 설치된 폭탄이 모두 폭발한다.
  • 3과 4를 반복한다.

폭탄을 설치해놓은 초기 상태가 주어졌을 때, N초가 흐른 후의 격자판 상태를 구하려고 한다.

예를 들어, 초기 상태가 아래와 같은 경우를 보자.

... .O. ...

1초가 지난 후에는 아무 일도 벌어지지 않기 때문에, 위와 같다고 볼 수 있다. 1초가 더 흐른 후에 격자판의 상태는 아래와 같아진다.

OOO OOO OOO

1초가 지난 후엔 가운데에 있는 폭탄이 폭발해 가운데 칸과 인접한 네 칸이 빈 칸이 된다.

O.O ... O.O

입력

첫째 줄에 R, C, N (1 ≤ R, C, N ≤ 200)이 주어진다. 둘째 줄부터 R개의 줄에 격자판의 초기 상태가 주어진다. 빈 칸은 '.'로, 폭탄은 'O'로 주어진다.

출력

총 R개의 줄에 N초가 지난 후의 격자판 상태를 출력한다.

 

풀이 코드 

package newProject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class 봄버맨 {
	public static void main(String[] args) throws IOException {
		BufferedReader br= new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		int R = Integer.parseInt(st.nextToken());
		int C = Integer.parseInt(st.nextToken());
		int N = Integer.parseInt(st.nextToken());
		
		StringBuilder sb = new StringBuilder();
		int[][] boom = new int[R][C];
		for(int i =0; i< R; i++) {
			char [] tmp = br.readLine().toCharArray();
			for(int j = 0; j< C; j++) {
				boom[i][j]= tmp[j]=='O'?3:0;// 터지기 까지 남은 시간 
			}
		}
		for(int n =2; n<= N; n++) {
			if(n%2==1) {
				for(int i =0; i< R; i++) {
					for(int j =0; j< C; j++) {
						if(boom[i][j]==n) {
							boom[i][j] = 0;
							if(i>0 && boom[i-1][j]!=n)boom[i-1][j]=0;
							if(j>0 && boom[i][j-1]!=n)boom[i][j-1]=0;
							if(i<R-1 && boom[i+1][j]!=n)boom[i+1][j]=0;
							if(j<C-1 && boom[i][j+1]!=n)boom[i][j+1]=0;
						}
					}
				}
			}else {
				for(int i=0; i<R; i++) {
					for(int j =0; j< C; j++) {
						boom[i][j]= boom[i][j]==0?n+3:boom[i][j];
					}
				}
			}
		}
		for(int i=0; i<R; i++) {
			for(int j =0; j< C; j++) {
				sb.append(boom[i][j]>0?'O':'.');
			}
			sb.append('\n');
		}
		System.out.println(sb);
	}
}

 

짝수 초에는 폭탄 넣기 

홀수 초에는 폭탄 터트리기 

이렇게 생각해서 풀면 해결되는 문제이다.  사실 그 초에 딱딱 맞추어 뭐가 이루어 지는지 생각할 시간이 좀 필요했다. 

먼저 반복문을 돌면서 터지기 까지 남은 시간들을 넣는다.  이 값과 현재를 비교해서 계산을 진행한다. 

0초와 1초일 때는 아무 작업도 일어나지 않는다고 하였으니 2초부터 시작해서 N초까지 진행한다. 

먼저 폭탄이 터지는 경우는 n이 홀수일 때이다, 3초 5초, 7초 9 초 이런식으로 홀수 때에만 폭탄이 터지게 된다. 

만약 boom[i][j]가 현재 의 초와 일치한다면, 

boom[i][j[의 값을 0으로 바꾸고, 상하좌우 처리도 해준다.

여기서 주의할 점이 만약 같은 초인 값을 미리 삭제하면 그 다음 상하좌우가 없어지지 않으니 그 경우는 제외하고, 0으로 바꿔준다. 

 

그리고 2,4,6초의 경우 폭탄이 터질 일이 없으므로 , 현재 자리에 폭탄ㄴ이 없는경우 (boom[i][j]==0) 이면 현재 초에서 3을 더한 값을 boom에 넣어준다. 

초가 모두 끝나면, boom[i][j]가 0인지 아닌지 여부에 따라 'O'과 '.'을 StringBuilder에 담아 출력해주면 된다.