๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿง  ์•Œ๊ณ ๋ฆฌ์ฆ˜

[๋ฐฑ์ค€] 4179 ๋ถˆ! js ํ’€์ด

by megan07 2023. 12. 27.

๐Ÿ’ก ์ ‘๊ทผ๋ฐฉ์‹ 

- ๊ฐ€์žฅ ๋นจ๋ฆฌ ํƒˆ์ถœ ํ•  ์ˆ˜ ์žˆ๋Š” ์‹œ๊ฐ„

- ๋ถˆ์€ ์ธ์ ‘ ์˜์—ญ์œผ๋กœ ์ด๋™

-> BFS!!

 

1. ๋ถˆ์ด ๋ฒˆ์ง€๋Š” ์‹œ๊ฐ„์„ ๋จผ์ € bfs๋กœ ๊ตฌํ•˜๊ณ 
2. ์ง€ํ›ˆ์ด๊ฐ€ ์ด๋™ํ•˜๋Š” ์‹œ๊ฐ„์ด ๋ถˆ์ด ๋ฒˆ์ง€๋Š” ์‹œ๊ฐ„๋ณด๋‹ค ์งฆ์œผ๋ฉด ์ด๋™ ๊ฐ€๋Šฅ

class Node {
  constructor(value) {
    this.value = value;
    this.next = null;
  }
}

class Queue {
  constructor() {
    this.first = null;
    this.last = null;
    this.size = 0;
  }
  enqueue(val) {
    const newNode = new Node(val);
    if (!this.first) {
      this.first = newNode;
      this.last = newNode;
    } else {
      this.last.next = newNode;
      this.last = newNode;
    }
    return ++this.size;
  }

  dequeue() {
    if (!this.first) return null;

    const tmp = this.first;
    if (this.first === this.last) {
      this.last = null;
    }
    this.first = this.first.next;
    this.size--;
    return tmp.value;
  }
}

const filePath = process.platform === 'linux' ? '/dev/stdin' : './input.txt';
//์ž…๋ ฅ๊ฐ’ 1๊ฐœ(1์ค„)
// const input = require('fs').readFileSync(filePath).toString().trim();

//์ž…๋ ฅ๊ฐ’ ์—ฌ๋Ÿฌ๊ฐœ (1์ค„)
// let input = require('fs').readFileSync(filePath).toString().trim().split(' ');

//์ž…๋ ฅ๊ฐ’ ์—ฌ๋Ÿฌ ์ค„
// let input = require('fs').readFileSync(filePath).toString().trim().split('\n');

// ์ž…๋ ฅ๊ฐ’์ด ์ฒซ ๋ฒˆ์งธ ์ค„์—๋Š” ์ž…๋ ฅ ๊ฐ’์˜ ๊ธธ์ด(n), n๊ฐœ์˜ ์ค„์— ๊ฑธ์ณ์„œ ํ•œ ์ค„์— ํ•˜๋‚˜์˜ ์ž…๋ ฅ๊ฐ’์ด ์ฃผ์–ด์งˆ ๋•Œ
const [n, ...input] = require('fs')
  .readFileSync(filePath)
  .toString()
  .trim()
  .split('\n');

function solution(row, col, maze) {
  const queue = new Queue();
  const fireQueue = new Queue();

  const dr = [1, -1, 0, 0];
  const dc = [0, 0, 1, -1];

  let min = Infinity;

  const fireMaze = [];
  maze.forEach((row) => {
    fireMaze.push([...row]);
  });

  let start = null;
  let fire = null;

  for (let i = 0; i < row; i++) {
    for (let j = 0; j < col; j++) {
      if (maze[i][j] === 'J') {
        start = { r: i, c: j, cnt: 0 };
      } else if (maze[i][j] === 'F') {
        fire = { r: i, c: j, cnt: 0 };
        fireQueue.enqueue({ r: i, c: j, cnt: 0 });
      }
    }
  }

  //๋ฐ”๋กœ ํƒˆ์ถœ ๊ฐ€๋Šฅํ•œ ์กฐ๊ฑด
  if (
    start.r === 0 ||
    start.r === row - 1 ||
    start.c === 0 ||
    start.c === col - 1
  ) {
    return 1;
  }

  //๋ถˆ์ด ๋ฒˆ์ง€๋Š” ์†๋„ bfs๋กœ ๋จผ์ € ๊ตฌํ•˜๊ธฐ
  while (fireQueue.size) {
    const { r, c, cnt } = fireQueue.dequeue();

    for (let i = 0; i < 4; i++) {
      if (
        r + dr[i] >= 0 &&
        r + dr[i] < row &&
        c + dc[i] >= 0 &&
        c + dc[i] < col &&
        fireMaze[r + dr[i]][c + dc[i]] === '.'
      ) {
        const tmp = { r: r + dr[i], c: c + dc[i], cnt: (cnt || 0) + 1 };
        fireMaze[r + dr[i]][c + dc[i]] = tmp.cnt;
        fireQueue.enqueue({ ...tmp });
      }
    }
  }

  //์ง€ํ›ˆ์ด ํƒˆ์ถœ bfs ๊ตฌํ•˜๊ธฐ
  queue.enqueue(start);
  while (queue.size) {
    const { r, c, cnt } = queue.dequeue();

    for (let i = 0; i < 4; i++) {
      if (
        r + dr[i] >= 0 &&
        r + dr[i] < row &&
        c + dc[i] >= 0 &&
        c + dc[i] < col &&
        maze[r + dr[i]][c + dc[i]] === '.'
      ) {
        const tmp = { r: r + dr[i], c: c + dc[i], cnt: cnt + 1 };

        //๋ถˆ์ด ์—†๋Š” ๊ฒฝ์šฐ
        if (!fire) {
          maze[r + dr[i]][c + dc[i]] = { ...tmp };
          queue.enqueue({ ...tmp });
        }
        //๋ถˆ์ด ์žˆ๋Š”๋ฐ ๋ฒฝ์— ๋ง‰ํ˜€์„œ ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ, ๋ถˆ์ด ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” ๊ฒฝ์šฐ
        else if (
          fireMaze[tmp.r][tmp.c] === '.' ||
          tmp.cnt < fireMaze[tmp.r][tmp.c]
        ) {
          maze[r + dr[i]][c + dc[i]] = { ...tmp };
          queue.enqueue({ ...tmp });
        }
      }
    }
  }

  for (let i = 0; i < row; i++) {
    for (let j = 0; j < col; j++) {
      if (
        typeof maze[i][j] === 'object' &&
        (i === 0 || i === row - 1 || j === 0 || j === col - 1)
      ) {
        min = Math.min(min, maze[i][j]['cnt']);
      }
    }
  }

  return min !== Infinity ? min + 1 : 'IMPOSSIBLE';
}

const nArr = n.split(' ').map(Number);

const answer = solution(
  nArr[0],
  nArr[1],
  input.map((row) => row.split('')),
);

console.log(answer);