[백준/BOJ] 12789번 도키도키 간식드리미 (Javascript / Node js)

2023. 10. 31. 02:58코딩 테스트 (BOJ)

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

 

12789번: 도키도키 간식드리미

인하대학교 학생회에서는 중간, 기말고사 때마다 시험 공부에 지친 학우들을 위해 간식을 나눠주는 간식 드리미 행사를 실시한다. 승환이는 시험 기간이 될 때마다 간식을 받을 생각에 두근두

www.acmicpc.net

 

문제 해석

문제는  위 그림에 "한 명씩만 설 수 있는 공간"을 활용하여 "간식받는 곳"에

수들을 오름차순으로 받아올 수 있을 경우에는 "Nice"를 출력하고

 

"한 명씩만 설 수 있는 공간"을 활용하여도 "간식받는 곳"에

수들을 오름차순으로 받아올 수 없을 경우에는 "Sad"를 출력하면 되는 문제이다.

 

우선 설명하기에 앞서 일단 편의를 위해, 그리고 구현된 전체 코드를 더 쉽게 이해하기 위해

간식 받는 곳을 "stack-snack", 한 명씩 설 수 있는 공간을 "stack-wait", 그리고 현재 줄 서 있는곳을 "arr"로 정의하겠다.

 

 

먼저 "Nice" 의 경우를 살펴보자.

 

 

가장 먼저 arr의 Top부분에 위치한 숫자가 stack-snack의 Top에 위치한 숫자에 1을 더한 숫자인지 검사한다.

 

[stack-snack의 Top에 위치한 숫자에 1을 더한 숫자]가 맞다면 stack-snack에 push해준다. - 예시 : STEP - 1

(이 로직이 arr의 값이 1일 때부터 유효하도록 stack-snack 배열을 초기화할 때 0을 디폴트로 넣어준다.)

 

[stack-snack의 Top에 위치한 숫자에 1을 더한 숫자]가 아니라면 stack-wait의 Top에 위치한 숫자도 마찬가지로

stack-snack의 Top에 위치한 숫자에 1을 더한 숫자인지 검사한다. stack-wait의 Top도 조건에 부합하지 않다면 

 

마지막으로  (arr의 Top < stack-wait) 인지 검사한뒤 아니라면 "Sad"를 출력하고, 맞다면

arr의 Top을 stack-wait에 push한다. - 예시 : STEP - 2 -> 3 -> 4

 

 

 

(arr의 Top < stack-wait)을 검사하는 이유는 아래 "Sad"의 예시에서 확인할 수 있다.

 

[STEP 3]의 경우를 보면 stack-wait과 arr의 Top이 모두 stack-snack에 push할 수 없는 숫자들인 것을 볼 수 있다.

이렇게 되면 위에서 설명했듯이 5 (arr의 Top) 를 stack-wait에 push해줘야 하는데,

 

5 (arr의 Top) 를 stack-wait에 push하면 [STEP 4]처럼 5 밑에 4가 깔려버려서 어떤 경우에도 수가 오름차순으로 정렬 될 수 없게 되버린다. ( 1 2 3 5 4 ~ )

 

 

 

 


 

 

 

위 내용을 요약하면,

 

arr를 pop 할때마다 아래의 조건 중 해당되는 케이스가 있는지 검사한다.

1.가장 먼저 arr의 Top부분에 위치한 숫자가 stack-snack의 Top에 위치한 숫자에 1을 더한 숫자인지

2. stack-wait의 Top에 위치한 숫자도가 stack-snack의 Top에 위치한 숫자에 1을 더한 숫자인지

3. arr의 Top < stack-wait 인지

위 조건중 어느 것도 충족하지 않는다면 "Sad"를 출력한다.

 

그리고 stack-snack에 모든 수가 들어올때까지 "Sad"를 출력하지 않았다면 "Nice"를 출력한다.

 

 

전체 코드
const fs = require("fs");

class main {
  constructor() {}

  checkOrder(input) {
    let arr = input.map((item) => Number(item));
    let stackSnack = [0];
    let stackWait = [];

    while (stackSnack.length <= arr.length) {
      const ARR_TOP = 0;
      const STACK_SNACK_TOP = stackSnack.length - 1;
      const STACK_WAIT_TOP = stackWait.length - 1;

      if (stackSnack[STACK_SNACK_TOP] + 1 == arr[ARR_TOP]) {
        stackSnack.push(arr.shift());
      } else if (
        STACK_WAIT_TOP != -1 &&
        stackSnack[STACK_SNACK_TOP] + 1 == stackWait[STACK_WAIT_TOP]
      ) {
        stackSnack.push(stackWait.pop());
      } else {
        if (stackWait[STACK_WAIT_TOP] > arr[ARR_TOP] || STACK_WAIT_TOP == -1) {
          stackWait.push(arr.shift());
        } else {
          return "Sad";
        }
      }
    }

    return "Nice";
  }

  exe() {
    const input = fs
      .readFileSync("../input.txt")
      .toString()
      .trim()
      .split("\n")
      .map((item) => item.split(" "));
    input.shift();

    const answer = this.checkOrder(input[0]);

    console.log(answer);
  }
}

const app = new main();

app.exe();