Sqsung DevLog

[백준] 16918번: 봄버맨 (Node.js) 본문

Algorithm

[백준] 16918번: 봄버맨 (Node.js)

sqsung 2023. 5. 17. 14:14

백준에서 16918번: 봄버맨(난이도: Silver I) 확인하기 

 

 

1 . 풀이 (Node.js)

const [info, ...input] = require('fs').readFileSync('/dev/stdin').toString().trim().split('\n');

const [Y, X, N] = info.split(' ').map(val => +val);
const maxBombBoard = Array.from({ length: Y }).fill('O'.repeat(X)).join('\n');
const board = input.map(row => [...row]);
const dirs = [ [0, 1], [0, -1], [-1, 0], [1, 0] ];

const initialize = () => {
  for (let i = 0; i < board.length; i++) {
    for (let j = 0; j < board[i].length; j++) {
      if (board[i][j] === 'O') board[i][j] = 0;
    }
  }
};

const explode = (x, y, bombTime) => {
  board[y][x] = '.';

  for (let i = 0; i < 4; i++) {
    const xPos = x + dirs[i][0];
    const yPos = y + dirs[i][1];

    if (xPos < 0 || yPos < 0 || xPos >= X || yPos >= Y) continue;

    if (bombTime !== +board[yPos][xPos]) board[yPos][xPos] = '.';
  }
};

const tick = () => {
  if (N % 2 === 0) return maxBombBoard;

  for (let i = 1; i <= N; i++) {
    if (i === 1) {
      initialize();

      continue;
    } else if (i % 2 === 0) {
      for (let y = 0; y < board.length; y++) {
        board[y] = board[y].map(string => (string === '.' ? i : string));
      }
    } else {
      for (let y = 0; y < board.length; y++) {
        for (let x = 0; x < board[y].length; x++) {
          if (i - +board[y][x] === 3) {
            explode(x, y, +board[y][x]);
          }
        }
      }
    }
  }

  return board.map(row => row.map(string => (string === '.' ? string : 'O')).join('')).join('\n');
};

console.log(tick());

 

1-1. 풀이 설명

 

격자판을 초기화 하면서 폭탄은 모두 심어진 시간, 즉 반복문의 순회 index로 저장해줬다. 이렇게 하니까 반복문을 돌면서 3초가 지났는지, 즉 폭탄이 터질 때가 됐는지 확인하기 수월했다. 

 

또한, 초 별로 격자판 상태를 공책에 그려가며 문제에 접근했는데, 덕분에 N이 짝수일 때는 무조건 봄버맨이 격자판의 빈 공간을 폭탄으로 설치해둔다는 점을 빨리 깨달았다. 그래서 tick 함수 내부에서 N이 짝수인지 우선 확인하고, 짝수인 경우 폭탄으로 꽉 찬 격자판(maxBombBoard)을 반환했다.

 

추가로 중요했던 부분이 있다면, 처음에는 explode 함수를 호출할 때 x, y 값만 전달했다. "폭발 지점과 인접한 폭탄은 연쇄 반응 없이 사라진다고" 기재되어 있어서 별 다른 처리 없이 폭발 지점과 인접한 모든 칸은 마침표로 바꿔주면 될 것이라고 착각했다. 하지만 이러한 경우 동일하게 설치된 폭탄, 즉 이번 차례에 폭발해야 하는 폭탄까지 없애버린다. 그래서 폭탄을 설치한 시간(bombTime)을 explode 함수에 같이 넘겨주어 좌우상하에 위치한 값과 일치하는지 확인한 후 마침표로 바꿨다.