BOJ/그래프 이론

[C/C++] 백준 - 16918번 : 붐버맨

JWonK 2022. 5. 3. 12:01
728x90
반응형

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

 

16918번: 봄버맨

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

www.acmicpc.net

문제

봄버맨은 크기가 R×C인 직사각형 격자판 위에서 살고 있다. 격자의 각 칸은 비어있거나 폭탄이 들어있다.

폭탄이 있는 칸은 3초가 지난 후에 폭발하고, 폭탄이 폭발한 이후에는 폭탄이 있던 칸이 파괴되어 빈 칸이 되며, 인접한 네 칸도 함께 파괴된다. 즉, 폭탄이 있던 칸이 (i, j)인 경우에 (i+1, j), (i-1, j), (i, j+1), (i, j-1)도 함께 파괴된다. 만약, 폭탄이 폭발했을 때, 인접한 칸에 폭탄이 있는 경우에는 인접한 폭탄은 폭발 없이 파괴된다. 따라서, 연쇄 반응은 없다.

봄버맨은 폭탄에 면역력을 가지고 있어서, 격자판의 모든 칸을 자유롭게 이동할 수 있다. 봄버맨은 다음과 같이 행동한다.

  • 가장 처음에 봄버맨은 일부 칸에 폭탄을 설치해 놓는다. 모든 폭탄이 설치된 시간은 같다.
  • 다음 1초 동안 봄버맨은 아무것도 하지 않는다.
  • 다음 1초 동안 폭탄이 설치되어 있지 않은 모든 칸에 폭탄을 설치한다. 즉, 모든 칸은 폭탄을 가지고 있게 된다. 폭탄은 모두 동시에 설치했다고 가정한다.
  • 1초가 지난 후에 3초 전에 설치된 폭탄이 모두 폭발한다.
  • 3과 4를 반복한다.

폭탄을 설치해놓은 초기 상태가 주어졌을 때, N초가 흐른 후의 격자판 상태를 구하려고 한다.


단순 구현 문제이지만 문제 이해에 꽤나 시간이 걸린 문제이다.

각 경우를 수행하는(3,4번) 함수문과 폭발처리를 도맡아서 하는 함수 하나를 만들어 관심사를 분리해주었고, 

시간이 끝날 때까지 수행하는 반복문 안에 각 명령 수행 함수를 넣어주었다.

 

먼가 삼성 빡구현 문제까지는 아니지만 느낌이 비슷한 문제였다.

#include <algorithm>
#include <iostream>
#include <numeric>
#include <cstring>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <climits>
#include <set>
#include <map> 
#define fastio ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define ll long long	
#define ull unsigned long long
#define INF 987654321
#define Mod 1000000009
#define endl '\n'
#define ENDL cout << endl

using namespace std;

int R, C, N;
int board[200 + 1][200 + 1];

const int dy[] = { 1, -1, 0, 0 };
const int dx[] = { 0, 0, 1, -1 };

void input() {
	cin >> R >> C >> N;
	for (int i = 1; i <= R; i++) {
		string s;
		cin >> s;
		for (int j = 0; j < s.size(); j++) {
			if (s[j] == '.') {
				board[i][j + 1] = 0;
			}
			else {
				board[i][j + 1] = 1;
			}
		}
	}
}

bool isValid(int y, int x) {
	return (1 <= y && y <= R && 1 <= x && x <= C);
}

bool isTimeOut() {
	N--;
	if (!N) return false;
	return true;
}

void timing(vector<pair<int,int>> &v) {
	for (int i = 1; i <= R; i++) {
		for (int j = 1; j <= C; j++) {
			if (board[i][j] == 0) continue;
			board[i][j]++;
			if (board[i][j] >= 3) {
				v.push_back({ i, j });
			}
		}
	}
}

void installBomb(vector<pair<int, int>>& v) {
	for (int i = 1; i <= R; i++) {
		for (int j = 1; j <= C; j++) {
			if (board[i][j] != 0) {
				board[i][j]++;
			}
			else {
				board[i][j] = 1;
			}
		}
	}
}

void explosion(vector<pair<int,int>> &v) {
	for (auto t : v) {
		board[t.first][t.second] = 0;
		for (int i = 0; i < 4; i++) {
			int ny = t.first + dy[i];
			int nx = t.second + dx[i];


			if (!isValid(ny, nx)) continue;
			board[ny][nx] = 0;
		}
	}
	v.clear();
}

void printResult() {
	for (int i = 1; i <= R; i++) {
		for (int j = 1; j <= C; j++) {
			if (board[i][j] == 0) cout << ".";
			else cout << "O";
		}
		ENDL;
	}
}

void solution() {
	vector<pair<int, int>> chk;
	while (1) {
		if (!isTimeOut()) break;
		installBomb(chk);

		if (!isTimeOut()) break;
		timing(chk);
		explosion(chk);
	}
	printResult();
}

int main() {
	fastio;
	input();
	solution();

	return 0;
}

 

728x90
반응형