글 작성자: bbangson
반응형

https://www.acmicpc.net/problem/16918

 

16918번: 봄버맨

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

www.acmicpc.net

[백준] 16918번 - "봄버맨"


 

난이도 : 실버 1

 

 쉽게 헷갈릴 수 있는 구현 문제이지만, 코딩 테스트 용으로 많은 도움이 될 문제인 것 같습니다. 

 

제가 주목한 문제의 조건은

1. "연쇄 반응은 없다" -> 현재 위치의 폭탄이 터질 때, 인접한 폭탄은 터지지 않는다. 

2. "1초가 지난 후에 3초 전에 설치된 폭탄이 모두 폭발한다." -> 동시 폭발 

3. "3과 4를 반복한다" -> 처음 1,2,3,4를 수행하고 3과 4만 반복된다.

 

 문제에서 주어진 조건을 위와 같이 해석했습니다. 

 

 제가 주목했던 3개의 조건 중, 1번과 2번을 통해 폭탄을 터트릴 때 반복문을 통해 순차적으로 폭탄을 터트리고 제거하면 안 된다는 것을 깨달았습니다. (순차적으로 터트려도 주어진 Test Case는 통과하지만 제출할 때는 틀립니다.)

 

 2개의 반복문으로 동시 다발적으로 폭탄을 터트리도록 하였습니다.

첫 번째 반복문으로 현재 칸이 터질 수 있는지 아닌지 여부만 판단하고,

2번째 반복문에서 동시 다발적으로 폭탄을 터트려주는 로직으로 구현하였습니다. (이중 for문 아닙니다.)

 

 조건 3번을 통해, 폭탄을 설치하고 터트리는 행위만 반복하였습니다. 

다른 분들 코드를 보니 작성된 조건에 따라 4개의 순서로 %4를 하여 문제를 푸신 분들이 많았지만,

저는 "3과 4를 반복한다"는 조건에 초점을 맞춰, 2개의 순서만 반복하였습니다.

 

 문제에 주어진 조건 3을 수행할지, 4를 수행할지는 boolean button 변수로 제어하도록 하였습니다. 

이 값이 false면 조건 3(폭탄 설치), true면 조건 4(폭탄 폭발)입니다. 

 

 int seconds 변수는 시간 "초"를 의미하는 변수입니다. 입력을 받는 초기화된 시간 0초, 봄버맨이 아무 행위도 하지 않는 순간 1초는 입력 배열에 영향을 주지 않는다고 판단하여, while 문을 1초부터 시작하였습니다. 

 

 

- static  boom map [ ][ ];

 폭탄 유무 상태와, 폭탄이 설치된 시각을 저장하기 위한 boom 객체를 자료형으로 만들고 

이를 저장하기 위한 이중 배열 변수입니다.

 

- static  int dr [ ] = {1, -1, 0, 0};
- static  int dc [ ] = {0,0,1,-1};

폭탄이 폭파되고, 인접 칸의 폭탄을 제거하기 위한 사분면 배열 변수입니다. 

 

- void main()

 입력을 받아오고 전역 변수들을 초기화 및 선언해줍니다.

위에서 설명한 로직을 수행하고, 답을 출력합니다. 

 

- void plant(int r, int c, int s)

 폭탄을 설치하는, 문제에 주어진 조건 3을 수행하는 메서드입니다.

폭탄이 설치되어 있지 않은 칸에 폭탄을 설치합니다. 

현재 시간은 나타내는 int s를 인자로 받아 설치되는 폭탄에 시간을 같이 저장합니다. 

 

- void explode(int r, int c, int s)

 폭탄을 폭파하는, 문제에 주어진 조건 4를 수행하는 메소드입니다.

이중 배열 boolean 변수인 flag를 활용하여 현재 칸에 폭탄이 존재하고 3초 전에 설치된 폭탄인 지 판단합니다. 

 

폭발되어야 하는 칸은 true 값을 저장합니다. 폭발 되어야 하는 칸이면 인접한 칸들도 true 값으로 변경합니다. 

 

그다음 반복문을 통해 true 값으로 지정되어 있는 칸은 전부 폭파시킵니다. 

 

위와 같은 로직으로 하지 않고, 순차적으로 폭탄을 폭발시키면 동시적으로 폭탄이 터지는 로직이 아니게 됩니다. 

그래서 결국 문제에서 요구하는 조건과는 다르게 로직이 구현되어 문제는 틀리게 됩니다. 

 

  코드
public class BOJ_16918 {
	// BOJ / 16918번 / 봄버맨 / 구현, 시뮬레이션 , 그래프 / 실버1
	static boom map[][];
	static int dr[] = {1,-1,0,0};
	static int dc[] = {0,0,1,-1};
	public static void main(String[] args) throws IOException {
		
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer stk = new StringTokenizer(br.readLine(), " ");
		// 입력부
		int r = Integer.parseInt(stk.nextToken());
		int c = Integer.parseInt(stk.nextToken());
		int n = Integer.parseInt(stk.nextToken());
		map = new boom[r][c];
		
		for(int i=0; i<r; i++) {
			String str = br.readLine();
			for(int j=0; j<c; j++) {
				map[i][j] = new boom(str.charAt(j), 0);
			}
		}
		
		int seconds = 1;
		boolean button = false; // 3과 4를 반복한다. 
		while(seconds < n) {
			seconds++;
			if(!button) {
				plant(r,c, seconds);
			}
			else if(button) {
				explode(r,c, seconds);
			}
			button = !button;
		}
		// 출력부
		for(int i=0; i<r; i++) {
			for(int j=0; j<c; j++) {
				System.out.print(map[i][j].status);
			}
			System.out.println();
		}
	}
	// 폭탄 설치.
	public static void plant(int r, int c, int s) {
		for(int i=0; i<r; i++) {
			for(int j=0; j<c; j++) {
				boom now = map[i][j];
				char nowStatus = now.status;
				
				if(nowStatus == '.') {
					boom newBoom = new boom('O', s);
					map[i][j] = newBoom;
				}
			}
		}
	}
	// 폭탄 폭발.
	public static void explode (int r, int c, int s) {
		
		boolean flag[][] = new boolean[r][c];
		for(int i=0; i<r; i++) {
			for(int j=0; j<c; j++) {
				boom now = map[i][j];
				char nowStatus = now.status;
				int nowTime = now.time;
				
				// 폭탄이 존재하고 3초 전에 설치된 폭탄이면 
				if(nowStatus == 'O' && s - nowTime >= 3) {
					// 현재 위치의 폭탄 체크
					flag[i][j] = true;
					for(int t=0; t<4; t++) {
						int nr = i + dr[t];
						int nc = j + dc[t];
						
						// 주변 위치 폭탄 체크 
						if(nr >= 0 && nr <r && nc>= 0 && nc<c) {
							flag[nr][nc] = true;
						}
					}
				}
			}
		}
		// 동시 다발적 폭탄을 터트려줘야한다. 체크된 폭탄 제거 
		for(int i=0; i<r; i++) {
			for(int j=0; j<c; j++) {
				if(flag[i][j]) {
					//폭탄 제거
					boom remove= new boom('.' , 0);
					map[i][j] = remove;
				}
			}
		}
	}
	
	private static class boom {
		char status;
		int time;
		public boom (char status, int time) {
			this.status = status;
			this.time = time;
		}
	}
}

여러 사람들의 풀이를 봤지만, 저랑은 다르게 풀이한 것 같았습니다. 다른 분들의 코드보다 제 코드가 시간은 오래 걸리지만, 

저의 생각을 전달하고자 포스팅했습니다. 부족한 점이나 피드백 있으시면 지적 부탁드리겠습니다 :)

 

피드백 환영합니다.

 

반응형