[백준 / JS ] 3190 뱀 - 삼성 SW 역량 테스트 기출 문제

Urther·2022년 2월 8일
0

알고리즘

목록 보기
30/41
post-thumbnail

Problem | 3190 뱀

👍 초기 설정

1. board 설정

초기에 벽을 고려하는 편이 편할 것이라고 생각해서 벽을 두었는데,
x, y의 위치가 0 이하, n-1 이상 면 벽에 부딪힌 것으로 고려해도 된다.

2. 뱀의 위치 설정

뱀의 위치를 야매 큐로 구현했다.
/ 이 문제에서는 unshift 와 pop 만 사용해서 이렇게 적었다

🤝 고려해야하는 점

1. n초마다 변경되는 뱀의 머리 방향 (L/D)

자기자신의 몸과 부딪히는 경우

큐[0] - 머리 - 를 제외하고, 큐를 돌아주며 머리의 x, y 와 일치는 몸통 x,y 가 있는지 확인하고 있다면 반복문을 빠져나갔다.

사과가 있는 경우와 없는 경우

🍎 사과가 없는 경우

머리, 꼬리의 위치가 모두 변경된다.

이동하는 곳의 위치를 unshift 해주고,
현재 존재하는 꼬리를 pop 해준다.

🍎 사과가 존재하는 경우

뱀의 몸 길이만 늘어난다

snake라는 queue 에 사과의 위치만 unshift 해주면 된다.
+ 사과를 먹으면 사과가 없어져야한다.

💻 코드

const inputs = require("fs")
  .readFileSync(process.platform === "linux" ? "dev/stdin" : "input.txt")
  .toString()
  .trim()
  .split("\n");

// 입력값 처리
const n = Number(inputs.shift());
const k = Number(inputs.shift());

let board = Array.from(Array(n + 2), () => Array(n + 2).fill(0));
// board 벽 처리
for (let i = 0; i <= n; i++) {
  board[0][i] = 1;
  board[i][0] = 1;
  board[n + 1][i] = 1;
  board[i][n + 1] = 1;
}

// 사과가 있는 자리 : 2
for (let i = 0; i < k; i++) {
  let [apple_x, apple_y] = inputs.shift().split(" ").map(Number);
  board[apple_x][apple_y] = 2;
}

const l = Number(inputs.shift());
const dir = new Map();
for (let i = 0; i < l; i++) {
  let [second, direction] = inputs[i].split(" ");
  dir.set(Number(second), direction);
}

// 풀이 시작
const dx = [-1, 0, 1, 0];
const dy = [0, 1, 0, -1];

let current_dir = 1;
let snake = [];
let second = 0;

snake.push([1, 1]);

let flag = 0;
while (snake.length) {
  // 뱀 머리
  let [snake_x, snake_y] = snake[0];
  second++;
  // 현재 위치를 변경해야하는 경우
  if (dir.has(second - 1)) {
    let change_dir = dir.get(second - 1);

    if (change_dir === "D") {
      current_dir = (current_dir + 1) % 4;
    } else {
      current_dir = (current_dir + 3) % 4;
    }
  }

  // 현재 board 위의 snake 머리 위치
  let current_snake =
    board[snake_x + dx[current_dir]][snake_y + dy[current_dir]];

  /* 조건문
  1. 벽을 만나는 경우
  2. 사과가 있는 경우 - 뱀의 길이만 늘어난다 
  3. 사과가 없는 경우 */
  if (current_snake === 1) break;
  else {
    let move_head_x = snake_x + dx[current_dir];
    let move_head_y = snake_y + dy[current_dir];

    snake.unshift([move_head_x, move_head_y]);
    if (current_snake === 2) {
      // 사과를 없애줌
      board[move_head_x][move_head_y] = 0;
    }
    if (current_snake !== 2) {
      for (let i = snake.length - 1; i >= 1; i--) {
        let [tmpx, tmpy] = snake[i];
        if (tmpx === move_head_x && tmpy === move_head_y) {
          flag = 1;
          break;
        }
      }
      snake.pop();
    }
  }
  if (flag) break;
}
console.log(second);
profile
이전해요 ☘️ https://mei-zy.tistory.com

0개의 댓글