개발새발 로그

[JS] 백준 3190번 : 뱀 본문

알고리즘

[JS] 백준 3190번 : 뱀

이즈흐 2023. 6. 30. 16:32

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

 

3190번: 뱀

'Dummy' 라는 도스게임이 있다. 이 게임에는 뱀이 나와서 기어다니는데, 사과를 먹으면 뱀 길이가 늘어난다. 뱀이 이리저리 기어다니다가 벽 또는 자기자신의 몸과 부딪히면 게임이 끝난다. 게임

www.acmicpc.net

 

풀이방법

1. 사과좌표를 보드안에 넣는다.

2. while반복문을 통해 1초마다 반복한다.

3. fow라는 값을 줘서 처음에는 오른쪽부터 이동하게한다.

4. [0,0]부터 fow라는 방향으로 앞에 1칸씩 확인한다.(x+nx,y+ny)

5. 만약 앞에가 벽이거나 뱀의 몸이라면 break

 -answer에 +1을해서 답을 출력한다.(왜냐면 확인만했고 시간은 증가안했으니)

6.만약 갈 수 있는 공간이라면 

 a. 만약 갈 수 있는 공간에 사과가 있다면

  - 일단 그 공간을 뱀의 공간 2로 만들고(뱀을 늘어뜨림)

  - queue에 해당경로를 push한다.

  - 뱀의 머리인 x와 y 좌표는 한칸 앞으로 증가한 nx와 ny로 바꾼다.

 b.만약 갈 수 있는 공간에 사과가 없다면 

  -뱀의 머리인 x와 y좌표를 한 칸 앞으로 증가한 nx와 ny로 바꾼다.

  -nx ny좌표를 뱀의 공간으로 만든다.

  -nx ny를 queue에 넣는다.

  - 뱀의 꼬리 좌표인 kry,krx를 빈 공간 0으로 만든다.

  -kry와 krx는 queue의 맨 앞의 좌표를 가져와 바꿔준다.

7. 시간 증가

8. 시간이 만약 주어진 시간에 snk 배열의 값 도달한다면

 -왼쪽 오른쪽에 대한 상황에 맞게 fow값을 바꿔줌

 -snk배열 값 shift해줌

 -만약 snk가 0이면 더이상 주어진 방향전환이 없는 것이므로 이전 방향으로 쭉가야함

 - 주어진 방향전환이 있다면 snk에서 시간 값을 다시 가져와줌

내 제출

const fs = require("fs");
const filePath = process.platform === "linux" ? "/dev/stdin" : "./input.txt";
let input = fs.readFileSync(filePath).toString().trim();
input=input.replace(/\r/g,"").split("\n");

let N=Number(input.shift());
let appN=Number(input.shift());
let appW=[];
//오른쪽,위,아래,왼쪽
let dx=[1,0,0,-1];
let dy=[0,-1,1,0];
let arr=Array.from({length:N},()=>Array(N).fill(0));
for(var i=0;i<appN;i++){
    appW.push(input.shift().split(" ").map(Number));
    let [y,x]=appW[i];
    arr[y-1][x-1]= 1;
}
let snkN=Number(input.shift());
let snk=[];
for(var i=0;i<snkN;i++){
    snk.push(input.shift().split(" "));
}


let fow=0;//오른쪽 시작
let [y,x]=[0,0]
let answer=0;
let [krx,kry]=[0,0];
const path = [];

arr[y][x]=2
let changeT=+snk[0][0];

while(1){
    let nx=x+dx[fow];
    let ny=y+dy[fow];
    console.log(arr)
    if (nx < 0 || nx >= N || ny < 0 || ny >= N) break;
    else if (arr[ny][nx] === 2) break;
    else {
        if (arr[ny][nx] === 1) {
            arr[ny][nx] = 2;
            path.push([ny, nx]);
            x = nx;
            y = ny;
        } else if (arr[ny][nx] === 0) {
            x = nx;
            y = ny;
            arr[ny][nx] = 2;
            path.push([ny, nx]);
            arr[kry][krx] = 0;
            let next = path.shift();
            kry = next[0];
            krx = next[1];
        }
    }
    
    answer++;
    if (answer === changeT) {
        if (snk[0][1] === "D") {
            if(fow==0) fow=2
            else if(fow==1) fow=0;
            else if(fow==2) fow=3;
            else if(fow==3) fow=1;
        } else if (snk[0][1] === "L") {
            if(fow==0) fow=1
            else if(fow==1) fow=3;
            else if(fow==2) fow=0;
            else if(fow==3) fow=2;
        }
        snk.shift();
        if (snk.length === 0) changeT = 0;
        else changeT = +snk[0][0];
    }

    
};

console.log(answer+1)

 

 

 

💢어려웠던 이유

1. 문제를 제대로 파악하지않고 풀었다.

-> 주어진 시간이 0초에서 8초 , 8초에서 18초가 아니고

 0초에서 8초, 8초에서 10초였다.

2. 머리 좌표와 꼬리 좌표가 필요하다는 것을 몰랐다.

-사과를 먹었을 때는 머리 좌표만 증가하지만

-사과를 안먹었을 때에는 머리좌표와 꼬리좌표가 같이 증가해야한다.

3. 큐에 넣으면서 해야하는 것을 몰랐다.

-머리좌표와 꼬리 좌표를 큐에 넣으면서하면 편하다.

-머리좌표는 이동하면서 항상 큐에 삽입하고

-꼬리 좌표는 사과를 안먹었을때 머리좌표로 큐에 삽입했었던 좌표중 가장 오래된 좌표를 꺼내서 그 공간을 0으로 만들면된다.

4. 뱀의 방향은 if문으로 하드코딩을 했다.

 

728x90
반응형
LIST

'알고리즘' 카테고리의 다른 글

[JS] 백준 14499번 : 주사위 굴리기  (0) 2023.07.02
[JS] 백준 16236 : 아기상어  (0) 2023.07.01
[JS] 백준 5430번 : AC  (0) 2023.06.29
[JS] 백준 14500 : 테르로미노  (0) 2023.06.28
[JS] 백준 14503번 : 로봇청소기  (0) 2023.06.27