jiho_bae
Go devlog
jiho_bae
전체 방문자
오늘
어제
  • 분류 전체보기 (158)
    • JavaScript (38)
      • theory (34)
      • vanilla (4)
    • HTML & CSS (2)
    • Browser (3)
    • CS (6)
      • linux (1)
      • shell (2)
      • compiler (2)
    • DS & Algorithm (87)
      • theory (5)
      • basic (7)
      • programmers (30)
      • baekjoon (45)
    • Design Pattern (2)
    • Error (4)
    • Git & Github (4)
    • Tools (1)
    • 부트캠프 (4)
    • Small Tips (2)
    • Java (3)
    • test (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 자바스크립트 배열의 특수함
  • 자바스크립트 모듈 시스템
  • 13460 javascript nodejs
  • javascript use strict
  • 1753 최단경로 javascript
  • 자바스크립트 비동기 마이크로 태스크 큐와 렌더링 과정
  • 가사 검색 자바스크립트
  • 퀵정렬 자바스크립트
  • 병합정렬 자바스크립트
  • 대충만든자판 javascript
  • 자바스크립트 커링
  • 외벽 점검 javascript
  • safari invalid date error
  • 자바스크립트 이벤트 위임
  • 25632 소수 부르기 게임
  • 리액트 프로젝트 디버깅하기
  • 계수정렬 자바스크립트
  • 자바스크립트 sort는 왜 그모양일까
  • 덧칠하기 javascript
  • 리코쳇 로봇 javascript
  • 프로그래머스 숫자카드나누기 javascript
  • fetch 취소하기
  • 억억단을 외우자 javascript
  • 깃 이전 커밋에서 새 브랜치 만들기
  • 백준 자바스크립트 입력 템플릿
  • 카카오 코딩테스트 양궁대회 nodeJS
  • 자바스크립트 채팅방 스크롤
  • safari Date format NaN
  • 백준 17406 nodeJS
  • JavaScript

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
jiho_bae

Go devlog

DS & Algorithm/baekjoon

[백준] 3055번 탈출 - JavaScript(NodeJS)

2021. 7. 7. 20:30

문제

 

3055번: 탈출

사악한 암흑의 군주 이민혁은 드디어 마법 구슬을 손에 넣었고, 그 능력을 실험해보기 위해 근처의 티떱숲에 홍수를 일으키려고 한다. 이 숲에는 고슴도치가 한 마리 살고 있다. 고슴도치는 제

www.acmicpc.net

 

코드

const sol = (input) => {
  let answer = 0;
  const [R, C] = input[0].split(" ").map(Number);
  const map = input.slice(1).map((str) => str.split(""));
  const check = Array(R)
    .fill()
    .map((_) => Array(C).fill(0));

  let D, S;
  let water = [];
  for (let i = 0; i < R; i++) {
    for (let j = 0; j < C; j++) {
      if (map[i][j] === "D") D = [i, j];
      if (map[i][j] === "S") S = [i, j];
      if (map[i][j] === "*") water.push([i, j]);
    }
  }

  const dx = [0, 1, 0, -1];
  const dy = [1, 0, -1, 0];

  function spreadWater() {
    const spread = [];
    for (let [x, y] of water) {
      for (let i = 0; i < 4; i++) {
        const [nx, ny] = [x + dx[i], y + dy[i]];
        if (nx < 0 || ny < 0 || nx >= R || ny >= C) continue;
        if (map[nx][ny] === ".") {
          map[nx][ny] = "*";
          spread.push([nx, ny]);
        }
      }
    }
    water.push(...spread);
  }

  function bfs() {
    const queue = [];
    queue.push([...S, 0]);
    check[S[0]][S[1]] = 1;
    while (queue.length) {
      const len = queue.length;
      spreadWater();
      for (let cycle = 0; cycle < len; cycle++) {
        const [x, y, cnt] = queue.shift();
        if (x === D[0] && y === D[1]) {
          answer = cnt;
          return;
        }

        for (let i = 0; i < 4; i++) {
          const [nx, ny] = [x + dx[i], y + dy[i]];
          if (nx < 0 || ny < 0 || nx >= R || ny >= C) continue;
          if (map[nx][ny] === "*" || map[nx][ny] === "X" || check[nx][ny]) continue;
          check[nx][ny] = 1;
          queue.push([nx, ny, cnt + 1]);
        }
      }
    }
    return;
  }
  bfs();

  return answer || "KAKTUS";
};

const input = [];
require("readline")
  .createInterface(process.stdin, process.stdout)
  .on("line", (line) => {
    input.push(line);
  })
  .on("close", () => {
    console.log(sol(input));
    process.exit();
  });

 

풀이

티떱 숲의 지도는 R x C 행렬 형태이며 비어있는 곳은 ".", 물이 찬 곳은 "*", 돌은 "X"로 나타낸다.

 

고슴도치 S는 비버의 굴 D로 이동해 홍수를 피하려고 한다.

고슴도치는 매 분마다 현재 칸으로부터 상하좌우에 비어있는 칸으로 이동할 수 있고,
물이 찬 곳도 매 분마다 상하좌우로 퍼져나간다.

 

고슴도치가 비버의 굴 D에 가장 빨리 도착한 시간을 출력하고, 도착할 수 없다면 "KAKTUS" 를 출력한다.

 

풀이 방향

최단경로를 구하는 유형이므로, BFS를 활용한다.

 

고슴도치는 물이 찰 예정인 위치로 이동할 수 없다. 매 분마다 먼저 물을 퍼뜨리고 고슴도치를 이동시킨다.
1분 전에 이동했던 모든 위치에서, 상하좌우의 이동 가능성을 판별해야 다음 1분의 진행이 가능함을 유의한다.
고슴도치가 지나온 경로를 기록하면서 이미 지나온 경로는 다시 돌아가지 않도록 한다.

 

아래는 이해를 돕기 위해 코드에 주석을 달아두었다.

 

주석을 포함한 코드

const sol = (input) => {
  let answer = 0;
  const [R, C] = input[0].split(" ").map(Number); // R,C 값 받기
  const map = input.slice(1).map((str) => str.split("")); // map 행렬 선언
  const check = Array(R).fill().map((_) => Array(C).fill(0));
    // map 크기로 동일한 위치로의 이동을 방지할 배열 선언

  let D, S;
  let water = [];
  for (let i = 0; i < R; i++) {
    for (let j = 0; j < C; j++) {
      if (map[i][j] === "D") D = [i, j];
      if (map[i][j] === "S") S = [i, j];
      if (map[i][j] === "*") water.push([i, j]);
    }
  } // D,S, 물의 좌표를 찾는다.

  const dx = [0, 1, 0, -1];
  const dy = [1, 0, -1, 0];

  function spreadWater() {
    const spread = [];
    for (let [x, y] of water) {
      for (let i = 0; i < 4; i++) {
        const [nx, ny] = [x + dx[i], y + dy[i]];
        if (nx < 0 || ny < 0 || nx >= R || ny >= C) continue;
        if (map[nx][ny] === ".") {
          map[nx][ny] = "*";
          spread.push([nx, ny]);
        }
      }
    } // 현재 물들의 위치를 기준으로 상하좌우로 퍼뜨릴 수 있다면 모두 퍼뜨린다.
    water.push(...spread);
    // 퍼진 물의 위치들을 모두 모은 spread 배열의 원소들을 기존의 water 배열에 넣어준다.
  }

  function bfs() {
    const queue = [];
    queue.push([...S, 0]); // S가 고슴도치 위치이므로 여기서부터 시작한다.
    check[S[0]][S[1]] = 1;
    while (queue.length) {
      const len = queue.length; // 현재 queue에 담긴만큼 반복해야 "매 분" 조건이 완성된다.
      spreadWater(); // 매 분마다 먼저 물을 퍼뜨린다.
      for (let cycle = 0; cycle < len; cycle++) {
        const [x, y, cnt] = queue.shift();
        if (x === D[0] && y === D[1]) {
          answer = cnt;
          return;
        } // 고슴도치가 비버 굴에 들어갔다면 최단시간을 기록하고 종료한다.

        for (let i = 0; i < 4; i++) {
          const [nx, ny] = [x + dx[i], y + dy[i]];
          if (nx < 0 || ny < 0 || nx >= R || ny >= C) continue;
          if (map[nx][ny] === "*" || map[nx][ny] === "X" || check[nx][ny]) continue;
          check[nx][ny] = 1;
          queue.push([nx, ny, cnt + 1]);
        } // 상하좌우 이동 가능성을 보고, 이동이 가능하면 고슴도치가 이동한다.
      } // 이 블록까지 수행되어야 1분이 지난 것이다.
    }
    return;
  }
  bfs();

  return answer || "KAKTUS"; // 최단시간이 존재하면 출력하고 존재하지 않는다면(=0) KAKTUS 출력
};

// 백준에서 입력을 받는 코드이다.
const input = [];
require("readline")
  .createInterface(process.stdin, process.stdout)
  .on("line", (line) => {
    input.push(line);
  })
  .on("close", () => {
    console.log(sol(input));
    process.exit();
  });

 

저작자표시 (새창열림)

'DS & Algorithm > baekjoon' 카테고리의 다른 글

[백준] 2108번 통계학 - JavaScript(NodeJS)  (0) 2021.07.18
[백준] 2231번 분해합 - JavaScript(NodeJS)  (0) 2021.07.16
[백준] 1316번 그룹 단어 체커 - JavaScript(NodeJS)  (0) 2021.07.02
[백준] 1037번 약수 - JavaScript(NodeJS)  (0) 2021.07.01
[백준] 1152번 단어의 개수 - JavaScript(NodeJS)  (0) 2021.07.01
    'DS & Algorithm/baekjoon' 카테고리의 다른 글
    • [백준] 2108번 통계학 - JavaScript(NodeJS)
    • [백준] 2231번 분해합 - JavaScript(NodeJS)
    • [백준] 1316번 그룹 단어 체커 - JavaScript(NodeJS)
    • [백준] 1037번 약수 - JavaScript(NodeJS)
    jiho_bae
    jiho_bae
    하루에 한 걸음씩

    티스토리툴바