문제
- 폭탄은 3초 후 폭발 → 빈칸이 됨 (인접 4칸 포함)
- 폭탄도 함께 파괴되어 연쇄 폭발 반응 없음
- 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 |