꾸물꾸물 졔의 개발공부

[백준] 16918 봄버맨 - JAVA 본문

알고리즘/백준

[백준] 16918 봄버맨 - JAVA

체제 2023. 9. 11. 15:08

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

 

16918번: 봄버맨

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

www.acmicpc.net

 

 

[풀이]

  • 구현 (시뮬레이션) 문제이다.
  • 문자형으로 주어진 입력을 정수로 변환하여서 풀었다.
  • 0 = 빈칸, 1~3 = 폭탄의 남은 시간 
  • 즉, 처음 폭탄이 생길 때 배열의 값을 3으로 초기화 해준 후, 시간이 지날 때마다 -1
  • 폭탄의 값이 0이 되면 폭발 (+인접한 폭탄) 

 

🌟주의해야 할 부분 
폭탄을 터트리는 과정에서 "폭탄을 터트리고 빈칸이 될 칸"을 0으로 지정할 경우, 
3초가 지나서 폭탄이 터져야 할 칸방금 폭탄이 터진 칸같은 값 (=0) 으로 혼동될 수 있다. 
나같은 경우엔, 1초가 지난 후 폭탄이 터질 칸을 큐에 넣어서, 모든 경우를 탐색한 후에 한번에 0으로 바꿔주었음. 
source code ▶Bomb() 메소드의 Queue<int[]> bomb : 이번 1초가 지난 후 폭탄이 터질 위치 

 


 

[소스 코드]

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

public class Main {
	static int r,c;
	static int map[][]; 
	public static void main(String[] args) throws Exception{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
		StringTokenizer st; 
		
		st= new StringTokenizer(br.readLine(), " ");
		r= Integer.parseInt(st.nextToken());
		c= Integer.parseInt(st.nextToken()); 
		
		int n = Integer.parseInt(st.nextToken()); 
		
		map = new int[r][c];
		
		for(int i=0; i<r; i++) {
			String s= br.readLine(); 
			for(int j=0; j<c; j++) {
				char ch= s.charAt(j);
				if(ch=='.') map[i][j] =0;
				else map[i][j] = 3; 
			}
		}
		
		start(n); 
		print(); 
	}
	private static void print() {
		StringBuilder sb= new StringBuilder(); 
		for(int i=0; i<r; i++) {
			for(int j=0; j<c; j++) {
				if(map[i][j] == 0) sb.append('.'); 
				else sb.append('O'); 
			}
			sb.append("\n"); 
		}
		System.out.println(sb);
	}
	private static void start(int n) {
		timeGo(); 
		n--; 
		if(n==0) return; 
		
		while(true) {	
			plusBomb();
			n--; 
			if(n==0) return; 
	
			Bomb();
			n--; 
			if(n==0) return; 
		}


	}
	
	//봄버맨은 아무것도 하지 않지만, 그냥 폭탄있는 곳의 시간이 1초씩 줄어들게 
	private static void timeGo() {
		for(int i=0; i<r; i++) {
			for(int j=0; j<c; j++) {
				if(map[i][j] > 0) {
					map[i][j]--; 
				}
			}
		}
	}
	private static int dx[]= {-1,1,0,0};
	private static int dy[]= {0,0,-1,1}; 
	//3초가 지나서 터질 폭탄이 있다면 터트리기 
	private static void Bomb() {
		Queue<int[]> bomb = new LinkedList<int[]>(); 
		for(int i=0; i<r; i++) {
			for(int j=0; j<c; j++) {
				map[i][j]--; 
				//터져야 할 폭탄(4방에 있는거 같이) 
				if(map[i][j]==0) {
					for(int d=0; d<4; d++) {
						int ni = i+dx[d];
						int nj = j+dy[d]; 
						if(isOut(ni,nj)) continue;
						bomb.add(new int[] {ni,nj}); //인접한거 같이 터트리기 
					}
				}
			}
		}
		
		while(!bomb.isEmpty()) {
			int[] b = bomb.poll();
			map[b[0]][b[1]] = 0; 
		}
	}
	//폭탄이 설치되어 있지 않은 칸에 폭탄 설치
	private static void plusBomb() {
		for(int i=0; i<r; i++) {
			for(int j=0; j<c; j++) {
				if(map[i][j] == 0) map[i][j] = 3;
				else map[i][j]--; 
			}
		}
	}
	
	private static boolean isOut(int i, int j) {
		return i<0 || i>=r || j<0 || j>=c; 
	}
	
}//end of class