오늘 풀어본 문제는 BOJ 16918 봄버맨!
봄버맨은 크기가 R×C인 직사각형 격자판 위에서 살고 있다. 격자의 각 칸은 비어있거나 폭탄이 들어있다.
폭탄이 있는 칸은 3초가 지난 후에 폭발하고, 폭탄이 폭발한 이후에는 폭탄이 있던 칸이 파괴되어 빈 칸이 되며, 인접한 네 칸도 함께 파괴된다. 즉, 폭탄이 있던 칸이 (i, j)인 경우에 (i+1, j), (i-1, j), (i, j+1), (i, j-1)도 함께 파괴된다. 만약, 폭탄이 폭발했을 때, 인접한 칸에 폭탄이 있는 경우에는 인접한 폭탄은 폭발 없이 파괴된다. 따라서, 연쇄 반응은 없다.
봄버맨은 폭탄에 면역력을 가지고 있어서, 격자판의 모든 칸을 자유롭게 이동할 수 있다. 봄버맨은 다음과 같이 행동한다.
예를 들어, 초기 상태가 아래와 같은 경우를 보자.
...
.O.
...
1초가 지난 후에는 아무 일도 벌어지지 않기 때문에, 위와 같다고 볼 수 있다. 1초가 더 흐른 후에 격자판의 상태는 아래와 같아진다.
OOO
OOO
OOO
1초가 지난 후엔 가운데에 있는 폭탄이 폭발해 가운데 칸과 인접한 네 칸이 빈 칸이 된다.
O.O
...
O.O
[입력]
첫째 줄에 R, C, N (1 ≤ R, C, N ≤ 200)이 주어진다. 둘째 줄부터 R개의 줄에 격자판의 초기 상태가 주어진다. 빈 칸은 '.'로, 폭탄은 'O'로 주어진다.
[출력]
총 R개의 줄에 N초가 지난 후의 격자판 상태를 출력한다.
그래프 탐색 문제로 찾아 고른 문제인데 풀다보니 굳이 dfs, bfs 없이 단순하게 풀어도 될 것 같았다. 내가 느끼기엔 시뮬레이션에 가까운 것 같은,,?
1초부터 시작해서 매 초마다 규칙대로 격자판의 상태를 변화시켜주면 된다. 폭탄이 설치되고 3초가 지난 뒤에 터지기 때문에 각 폭탄이 설치된 시점을 저장할 2차원 배열 installTime
을 만들어서 관리 해 주었다.
폭탄이 설치 될 때마다 해당 시점을 기록 해주고 시점이 바뀔 때 마다 3초가 지났으면 폭탄을 폭파 시키고 installTime
값도 초기화 시켜준다.
#include <iostream>
#include <vector>
using namespace std;
vector<vector<char>> matrix;
vector<vector<int>> installTime;
int dy[5] = {0,-1,0,1,0};
int dx[5] = {0,0,1,0,-1};
void installBomb(int R, int C, int sec){
for (int i = 0; i < R; ++i) {
for (int j = 0; j < C; ++j){
if (matrix[i][j]=='.') {
matrix[i][j] = 'O';
installTime[i][j] = sec;
}
}
}
}
void removeBomb(int R, int C, vector<pair<int, int>> points){
for (int i = 0; i < points.size(); ++i) {
for (int k = 0; k < 5; ++k) {
int row = points[i].first+dy[k], col = points[i].second+dx[k];
if (row<0||row>=R||col<0||col>=C) continue;
matrix[row][col] = '.';
installTime[row][col] = -1;
}
}
}
void moveMan(int R, int C, int N){
int sec = 1;
while (sec<N){
sec++;
installBomb(R, C, sec);
if (sec==N) break;
sec++;
vector<pair<int, int>> remove_points;
for (int i = 0; i < R; ++i) {
for (int j = 0; j < C; ++j){
if (sec-installTime[i][j]==3){
remove_points.push_back({i,j});
}
}
}
removeBomb(R, C, remove_points);
}
}
int main() {
int R, C, N;
cin>>R>>C>>N;
matrix.assign(R, vector<char>(C, ' '));
installTime.assign(R, vector<int>(C, -1));
for (int i = 0; i < R; ++i) {
for (int j = 0; j < C; ++j) {
cin>>matrix[i][j];
if (matrix[i][j] =='O') installTime[i][j] = 0;
}
}
moveMan(R, C, N);
for (int i = 0; i < R; ++i) {
for (int j = 0; j < C; ++j){
cout<<matrix[i][j];
}
cout<<'\n';
}
return 0;
}