[ 백준 ] 12933 오리 - JavaScript

2025. 3. 29. 16:21·알고리즘

문제

오리의 울음 소리는 "quack"이다. 올바른 오리의 울음 소리는 울음 소리를 한 번 또는 그 이상 연속해서 내는 것이다. 예를 들어, "quack", "quackquackquackquack", "quackquack"는 올바른 오리의 울음 소리이다.

 

영선이의 방에는 오리가 있는데, 문제를 너무 열심히 풀다가 몇 마리의 오리가 있는지 까먹었다.

 

갑자기 영선이의 방에 있는 오리가 울기 시작했고, 이 울음소리는 섞이기 시작했다. 영선이는 일단 울음소리를 녹음했고, 나중에 들어보면서 총 몇 마리의 오리가 있는지 구해보려고 한다.

 

녹음한 소리는 문자열로 나타낼 수 있는데, 한 문자는 한 오리가 낸 소리이다. 오리의 울음 소리는 연속될 필요는 없지만, 순서는 "quack"이어야 한다. "quqacukqauackck"과 같은 경우는 두 오리가 울었다고 볼 수 있다.

 

영선이가 녹음한 소리가 주어졌을 때, 영선이 방에 있을 수 있는 오리의 최소 개수를 구하는 프로그램을 작성하시오.

 

입력

첫째 줄에 영선이가 녹음한 소리가 주어진다. 소리의 길이는 5보다 크거나 같고, 2500보다 작거나 같은 자연수이고, 'q','u','a','c','k'로만 이루어져 있다.

출력

영선이 방에 있을 수 있는 오리의 최소 수를 구하는 프로그램을 작성하시오. 녹음한 소리가 올바르지 않은 경우에는 -1을 출력한다.

 

입출력 예시

입력 1

quqacukqauackck

 

출력 1

2

 

입력 2

kcauq

 

출력 2

-1

 

 


 

 

풀이

'use strict';
const fs = require('fs');

// 백준 제출 할 때 주석 제거
// const readFileSyncAddress = '/dev/stdin';

// VSC 테스트 할 때 주석 제거
const readFileSyncAddress = 'input.txt';

const input = fs.readFileSync(readFileSyncAddress).toString().trim().split('\n');

let stack = [];

function findAndDelete(search) {
  const index = stack.indexOf(search);

  if (index !== -1) {
    stack.splice(index, 1);
    return true;
  }

  return false;
}

function solution(input) {
  let result = 0;
  let isSound = true;

  input.forEach(sound => {
    switch (sound) {
      case 'q':
        if (!findAndDelete('k')) result += 1;
        break;

      case 'u':
        if (!findAndDelete('q')) {
          isSound = false;
          return;
        }
        break;

      case 'a':
        if (!findAndDelete('u')) {
          isSound = false;
          return;
        }
        break;

      case 'c':
        if (!findAndDelete('a')) {
          isSound = false;
          return;
        }
        break;

      case 'k':
        if (!findAndDelete('c')) {
          isSound = false;
          return;
        }
        break;
    }

    stack.push(sound);
  });

  if (!isSound || stack.some(sound => sound !== 'k')) return -1;
  return result;
}

console.log(solution([...input[0]]));

💡 핵심 아이디어

"quack"은 반드시 q → u → a → c → k의 순서를 따라야 하며, 이 순서가 어긋나거나 일부가 빠지면 올바른 울음으로 간주할 수 없다.

 

또한 "quackquack"처럼 여러 번 연속된 울음도 한 마리의 울음으로 처리해야 하므로, 단순히 "quack"의 개수를 세는 것이 아닌, 동시에 울고 있는 오리의 흐름을 정확히 추적하는 것이 중요하다.

 

이를 위해 각 문자가 진행 중인 울음소리의 어느 단계에 있는지를 배열로 관리했는데,


예를 들어, u가 들어오면 앞서 등장한 q를 찾아 제거하고, a가 들어오면 u를 제거하는 식으로, 각 문자가 기존 울음의 연속인지, 혹은 새로운 울음의 시작인지를 판단한다.

 

 

알고리즘 흐름

1. 문자열을 한 글자씩 순회하면서

2. 현재 글자가 "quack" 중 어느 위치에 해당하는지를 판단

3. 이전 단계의 글자가 존재한다면 해당 글자를 스택에서 제거 (findAndDelete)

4. 없다면 울음소리의 순서가 틀렸으므로 isSound = false

5. k까지 완성된 후에도 해당 k는 스택에 남겨두고, q가 다시 오면 재사용 -> 여러 번 연속된 울음도 한 마리의 울음으로 처리 가능

6. 모든 글자를 다 돈 후, 유효하지 않은 상태가 남아있다면 -1 반환

 

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

[ 프로그래머스 ] 단속카메라 - JavaScript  (0) 2025.03.31
[ 백준 ] 11660 구간 합 구하기 5 - JavaScript  (0) 2025.03.31
[ 백준 ] 1541 잃어버린 괄호 - JavaScript  (0) 2025.03.29
[ 백준 ] 10799 쇠막대기 - JavaScript  (1) 2025.01.07
[ 백준 ] 1966 프린터 큐 - JavaScript  (0) 2025.01.07
'알고리즘' 카테고리의 다른 글
  • [ 프로그래머스 ] 단속카메라 - JavaScript
  • [ 백준 ] 11660 구간 합 구하기 5 - JavaScript
  • [ 백준 ] 1541 잃어버린 괄호 - JavaScript
  • [ 백준 ] 10799 쇠막대기 - JavaScript
seio924
seio924
seio924 님의 블로그 입니다.
  • seio924
    seio924 님의 블로그
    seio924
  • 전체
    오늘
    어제
    • ROOT (51)
      • Mark Up (1)
      • Style Sheet (1)
      • Language (5)
        • JavaScript (5)
      • CS (0)
      • 알고리즘 (26)
      • 디자인 패턴 (1)
      • Develop (8)
      • 디자인 툴 (1)
      • COCOMU (8)
      • FRIENDY (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    storybook
    특수문자 코드
    프로그래머스
    javascript
    merge
    html
    라이브러리 제작
    react
    이분탐색
    llm
    Pretendard
    BFS
    그리디
    figma
    s3
    완전탐색
    DFS
    DP
    gpt-error-analyzer
    백준
    cocomu
    spa fallback
    cogroom
    GPT
    배포
    CloudFront
    디스코드 봇 제작
    알고리즘
    Git
    코코무
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
seio924
[ 백준 ] 12933 오리 - JavaScript
상단으로

티스토리툴바