코딩테스트 준비/백준

[백준 16918] - 봄버맨(구현) C++

SeoburiFaust 2024. 3. 20. 15:30

문제

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

 

16918번: 봄버맨

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

www.acmicpc.net

접근방법

단순하게 폭발할 폭탄 좌표를 기억했다가, 폭탄 'O'를 만나면 폭발하면 된다고 생각했다.

 

하지만, 간과했던 부분이 있었다. '모두' 한번에 폭발한다는 가정이다. 나는 대수롭지 않게 생각했다. 그냥 한 바퀴 loop돌리면서 폭탄 제거하면 당연히 '모두' 한번에 폭발한 것과 같은 효과를 낼 수 있을 것이라는 기대를 했다. 하지만 생각과는 달랐다.

 

예를 들어서 1번과 같은 다음 케이스의 경우 폭발하고 나서 2번과 같은 모양이 되야하는데, 나는 O을 만나면 무조건 폭발하도록 구현해서.

다음 폭탄이 터져버리기때문에, 그 다음 폭탄은 터지지 않아 2번과 같은 모양이 아니라 다른 모양이 나오는 것이었다.

1.00..		2. ...O
  00..		   ...O
  ....		   ..OO

 

그래서 배열을 저장할 때, 폭탄이 놓일 곳에 숫자를 넣어 폭탄이 터질 타이밍을 저장해줘야 했다.

 

처음 폭탄은 3으로 설정했고, 1초가 지날 때마다 모든 폭탄에 -1을 해줬다.

 

그리고 폭탄이 터지는 현상을 두 파트로 나눠서 구현했다.

같은 시기에 놓인 폭탄 말고 다른 시기에 놓인 폭탄을 먼저 제거한 후에,

같은 시기에 놓인 폭탄을 같이 제거해줘야 했다.

 

코드

#define FOR(i, n) for(int i=0;i<n;i++) 

const int dy[] = {0, 0, -1, 1};
const int dx[] = {-1, 1, 0, 0};
int r, c, n;
int second;
int house[201][201];

void bomb() {
    FOR(i, r) FOR(j, c) {
        if (house[i][j] == 0) {
            FOR(w, 4) {
                int ny = i + dy[w];
                int nx = j + dx[w];
                if (ny >= 0 && ny < r && nx >= 0 && nx < c) {
                    if (house[ny][nx] <= 3 && house[ny][nx] > 0) house[ny][nx] = -1;
                }
            }
        }
    }
    FOR(i, r) FOR(j, c) {
        if (house[i][j] == 0) {
            house[i][j] = -1;
            FOR(w, 4) {
                int ny = i + dy[w];
                int nx = j + dx[w];
                if (ny >= 0 && ny < r && nx >= 0 && nx < c) {
                    house[ny][nx] = -1;
                }
            }
        }
    }
}

void fill_bomb() {
    FOR(i, r) FOR(j, c) {
        if (house[i][j] < 0) {
            house[i][j] = 3;
        }
    }
}

int main() {

    cin >> r >> c >> n;
    FOR(i, r) FOR(j, c) {
        char temp;
        cin >> temp;
        if (temp == 'O') house[i][j] = 3;
        else house[i][j] = -1;
    }
    second = 0;
    while(second < n){
        second++;
        FOR(i, r) FOR(j, c) if (house[i][j]) house[i][j]--;
        if (second == 1) continue;
        else { 
            if (second % 2 == 0) {
                fill_bomb();
            } else {
                bomb();
            }
        }
    }
    FOR(i, r) {
        FOR(j, c) {
            if (house[i][j] >= 0) cout << 'O';
            else cout << '.';
        }
        cout << endl;
    }

    return 0;
}

개선할 점

'모두' 한번에 폭발... -> for loop으로 돌면서 하나 씩 폭발하는 것으로 구현 불가능...

 

메모...