반응형
https://www.acmicpc.net/problem/16918
16918번: 봄버맨
첫째 줄에 R, C, N (1 ≤ R, C, N ≤ 200)이 주어진다. 둘째 줄부터 R개의 줄에 격자판의 초기 상태가 주어진다. 빈 칸은 '.'로, 폭탄은 'O'로 주어진다.
www.acmicpc.net
1.문제설명
폭탄은 3초가 지나야 터진다.
폭탄이 터지면 폭탄이 있던 자리와 인접한 상하좌우칸이 .이 된다.
폭탄이 터지는 인접 상하좌우에 폭탄이 있을 경우 상하좌우에 있던 폭탄은 그냥 사라진다.
2.접근방법
3초가 되는 폭탄을 따로 배열이나 벡터에 저장했다가
각각 터트려야 쉽게 구현할 수 있다.
만약 3초가 지난 폭탄을 따로 저장하지 않고 순차적으로 터트릴 경우
인접한 3초 폭탄이 사라져 다른 결과를 얻게 된다.
다음 표에서 3이 써있는 폭탄은 이제 터지는 폭탄이라고 두고
O는 아직 터지지 않는 폭탄이라 생각하자.
3 | 3 | O |
O | O | O |
O | O | O |
그냥 무지성으로 3인 폭탄을 for문으로 돌며 터트리면 다음과 같은 결과를 얻는다
X | X | O |
X | O | O |
O | O | O |
오른쪽에 있던 3폭탄이 터지지 못하고 그냥 묻혀버리고 만다.
다른 벡터에 3인 폭탄의 좌표를 모두 저장한 후 벡터에서 for문을 돌면서 터트리면
X | X | X |
X | X | O |
O | O | O |
이런 옳은 결과를 얻을 수 있다.
많은 시뮬레이션 문제에서 이렇게 정보를 저장한 후 실행하는 방법이 유용하게 쓰인다.
단순히 순차적으로 돌다보면 문제가 생기는 경우가 많다.
3.문제풀이코드 C++
#include <bits/stdc++.h>
using namespace std;
int r, c, n, T;
int a[201][201];
int dx[4] = { 1,0,-1,0 };
int dy[4] = { 0,1,0,-1 };
void print() {
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
if (a[i][j] == -1) {
cout << '.';
}
else cout << 'O';
}
cout << '\n';
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> r >> c >> n;
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
char tmp;
cin >> tmp;
if (tmp == 'O') {
a[i][j] = 0;
}
else {
a[i][j] = -1;
}
}
}
if (T == n) {
print();
return 0;
}
T++;
// 첫 1초 아무것도 안함
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
if (a[i][j] == 0) {
a[i][j]++;
}
}
}
if (T == n) {
print();
return 0;
}
T++;
//2초 모든칸 폭탄 설치
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
a[i][j]++;
}
}
if (T == n) {
print();
return 0;
}
while(T<n) {
T++;
vector<pair<int, int> > v;
// 아무것도 안함
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
if (a[i][j] >= 0) a[i][j]++;
if (a[i][j] == 3) {
v.push_back({ i,j });
}
}
}
for (int i = 0; i < v.size(); i++) {
a[v[i].first][v[i].second] = -1;
for (int k = 0; k < 4; k++) {
int nx = v[i].first + dx[k];
int ny = v[i].second + dy[k];
if (nx < 0 || nx >= r || ny < 0 || ny >= c) continue;
a[nx][ny] = -1;
}
}
v.clear();
if (T == n) break;
T++;
// 폭탄 설치
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
a[i][j]++;
if (a[i][j] == 3) v.push_back({ i,j });
}
}
for (int i = 0; i < v.size(); i++) {
a[v[i].first][v[i].second] = -1;
for (int k = 0; k < 4; k++) {
int nx = v[i].first + dx[k];
int ny = v[i].second + dy[k];
if (nx < 0 || nx >= r || ny < 0 || ny >= c) continue;
a[nx][ny] = -1;
}
}
}
print();
return 0;
}
반응형
'Algorithm > problem' 카테고리의 다른 글
백준 2812번 : 크게 만들기 (0) | 2022.02.10 |
---|---|
백준 11559번 : Puyo Puyo C++ 문제풀이코드 (0) | 2022.02.10 |
백준 17144번 : 미세먼지 안녕! C++ 코드 (0) | 2022.02.09 |
백준 17143번 : 낚시왕 (0) | 2022.02.09 |
백준 14890번 : 경사로 C++ (0) | 2022.02.09 |