독립 창작 문제: 상담 창구 대기열
도착한 순서를 지키며 고객을 호출하고 대기 인원을 출력합니다. 같은 이름의 고객도 각각 별도 방문으로 보관합니다.

이 문제는 BlogFlow 학습용으로 독립 창작했습니다. 외부 문제의 지문·예시·테스트를 복제하지 않았습니다.
개념 연결: 큐와 FIFO 가이드
문제
비어 있는 상담 창구에 명령이 순서대로 주어집니다. ARRIVE 이름은 고객을 대기열 뒤에 추가합니다. CALL은 가장 먼저 온 고객 이름을 출력한 뒤 대기열에서 제거하며, 비어 있으면 EMPTY를 출력합니다. COUNT는 현재 인원 수를 출력합니다. 이름이 같아도 도착한 횟수만큼 별도 항목으로 취급합니다.
입력·출력·제약
첫 줄은 정수 Q(0~100,000), 다음 Q줄은 정의된 명령입니다. 이름은 공백 없는 1~40 코드포인트 문자열입니다. CALL과 COUNT 결과를 각 한 줄로 출력하며 결과가 하나도 없으면 아무것도 출력하지 않습니다. 명령과 이름 사이에는 공백 하나를 사용합니다.
예시 1
입력:
7
ARRIVE 민수
ARRIVE 수지
CALL
ARRIVE 준호
COUNT
CALL
CALL
출력:
민수
2
수지
준호
예시 2: 빈 상태
입력:
2
CALL
COUNT
출력:
EMPTY
0
힌트
아직 읽지 않은 첫 위치 head를 움직이세요. 빈 큐는 값이 undefined인지가 아니라 head와 배열 길이가 같은지로 판단합니다.
정답 코드와 해설 펼치기
Node.js 24 CommonJS용 코드입니다. 전체를 queue-helpdesk-problem.cjs로 저장하고 예시 입력을 input.txt에 UTF-8로 저장합니다. 아래 명령은 셸에 맞게 하나를 골라 사용하세요.
PowerShell 7 (UTF-8 파이프):
Get-Content -Raw -Encoding UTF8 .\input.txt | node .\queue-helpdesk-problem.cjs
macOS / Linux Bash:
node queue-helpdesk-problem.cjs < input.txt
function createQueue() {
let items = [];
let head = 0;
return {
enqueue(value) {
items.push(value);
},
dequeue() {
if (head === items.length) {
return { done: true };
}
const value = items[head];
items[head] = undefined;
head += 1;
if (head === items.length) {
items = [];
head = 0;
} else if (head >= 1024 && head * 2 >= items.length) {
items = items.slice(head);
head = 0;
}
return { done: false, value };
},
size() {
return items.length - head;
},
};
}
function solve(input) {
const text = input.trim();
if (!text) {
return '';
}
const lines = text.split(/\r?\n/);
const count = Number(lines[0]);
const queue = createQueue();
const output = [];
for (let i = 1; i <= count; i++) {
const [command, name] = lines[i].split(' ');
if (command === 'ARRIVE') {
queue.enqueue(name);
} else if (command === 'CALL') {
const result = queue.dequeue();
output.push(result.done ? 'EMPTY' : result.value);
} else if (command === 'COUNT') {
output.push(String(queue.size()));
}
}
return output.join('\n');
}
module.exports = { solve };
if (require.main === module) {
const input = require('node:fs').readFileSync(0, 'utf8');
process.stdout.write(solve(input));
}
명령과 상태 변화
| 명령 | 처리 뒤 목록 | 출력 |
|---|---|---|
| ARRIVE 민수 | 민수 | 없음 |
| ARRIVE 수지 | 민수 → 수지 | 없음 |
| CALL | 수지 | 민수 |
| ARRIVE 준호 | 수지 → 준호 | 없음 |
| COUNT | 수지 → 준호 | 2 |
| CALL, CALL | 빈 큐 | 수지, 준호 |
왜 이 구현으로 맞는가
정답 파일은 createQueue 선언부터 solve, 표준 입력 처리까지 포함합니다. 다른 가이드 파일을 require하지 않습니다. Node 내장 fs만 표준 입력을 읽는 데 사용합니다. 유효 입력 계약을 가정하는 연습 풀이이며 잘못된 명령·누락 줄을 진단하는 파서는 아닙니다.
solve는 첫 줄의 명령 수를 읽고 정확히 그만큼 순회합니다. ARRIVE에는 반환할 결과가 없으므로 output에 넣지 않습니다. CALL은 dequeue의 done으로 빈 상태를 구분하고 COUNT는 size를 문자열로 바꿉니다. output.join("\n")은 결과 사이에만 줄바꿈을 넣어 Q=0일 때 빈 문자열을 반환합니다.
각 명령 직전 큐의 유효 구간에는 아직 호출하지 않은 방문만 도착 순으로 남아 있습니다. enqueue가 뒤에 추가하고 dequeue가 앞의 한 항목만 제거하므로 명령 처리 뒤에도 이 불변식은 유지됩니다. COUNT가 전체 items.length를 읽으면 이미 호출한 슬롯까지 세므로 반드시 size를 사용합니다.
head가 커지면 소비한 앞부분이 물리 배열에 남습니다. dequeue는 사용한 슬롯의 참조를 먼저 끊고, 충분히 많은 슬롯을 소비했을 때 남은 값만 복사합니다. 한 압축은 O(K)이지만 그 비용을 앞선 제거들에 나누면 큐 연산은 분할 상환 O(1)입니다.
시간·공간과 문자열 비용
큐에 남은 최대 항목 수를 K라 하면 큐 구조만의 공간은 O(K+1024)입니다. 그러나 이 프로그램은 전체 입력 문자열, 줄 배열, 출력 배열과 마지막 결합 문자열까지 메모리에 보관합니다. 입력 문자 수 S, 출력 문자 수 R, 명령 수 Q를 포함한 전체 추가 저장은 O(S+R+Q+K), K≤Q이므로 O(S+R+Q)입니다. 따라서 프로그램 전체 공간을 O(K)라고 쓰면 입력·출력을 빠뜨립니다. 문자열 처리까지 포함한 총시간은 통상적 동적 배열 모델에서 O(S+R+Q) 상환이며, 큐 연산만 따로 보면 O(Q) 상환입니다.
표본을 직접 확인하는 코드
다음 코드를 queue-helpdesk-check.cjs로 저장한 뒤 node queue-helpdesk-check.cjs로 실행하세요. assert가 일치하면 출력 없이 종료하고, 결과가 다르면 예외가 발생합니다. 같은 폴더의 정답 파일을 가져오는 이 블록은 풀이 본체가 아니라 표본 확인용입니다.
const assert = require('node:assert/strict');
const { solve } = require('./queue-helpdesk-problem.cjs');
const input = "7\nARRIVE 민수\nARRIVE 수지\nCALL\nARRIVE 준호\nCOUNT\nCALL\nCALL";
const expected = "민수\n2\n수지\n준호";
assert.equal(solve(input), expected);
assert.equal(solve("2\nCALL\nCOUNT"), "EMPTY\n0");
assert.equal(solve('0'), '');
연결 학습
큐와 FIFO 가이드에서 메서드별 불변식을 확인하세요. 공식 문제 사이트의 백준 10845 큐는 다른 계약을 가진 추가 연습입니다. 공식 링크 확인일: 2026년 9월 10일.
풀이 전에 확인할 순서
- 입력값과 출력값을 한 문장으로 다시 적습니다.
- 반복할 대상과 비교·저장할 값을 정합니다.
- 필요한 자료구조와 시간복잡도를 예상합니다.
- 코드를 보기 전에 손으로 작은 예제를 계산합니다.
힌트: 코딩테스트 JS 큐: 상담 창구 대기열 명령 처리
정답 코드를 바로 따라 쓰기보다, 본문에서 값이 갱신되는 조건과 반복 범위를 먼저 찾으세요. 반복 한 번마다 반드시 유지되어야 하는 값이 무엇인지 적으면 풀이의 중심 변수를 고르기 쉽습니다.
테스트 확인
- 가능한 가장 작은 입력
- 같은 값이나 문자가 반복되는 입력
- 정답이 처음 또는 마지막 위치에서 결정되는 입력
- 입력 제한에 가까운 경우의 실행 시간
확인 결과: 본문의 예제뿐 아니라 위 경계 사례에서도 예상값과 실제 출력이 같아야 풀이가 완료됩니다.
이 글이 도움이 되었나요?
코딩테스트 JavaScript 학습 순서
필수 49개 · 전체 49개
읽음 기록 관리
전체 과정 목차 (49개)
- 필수 길잡이 · 코딩테스트 JS 자료구조 로드맵: 배열, 해시, 스택, 투 포인터 순서
- 필수 학습 · 세 수 중 최솟값 JavaScript 조건문 풀이 정리
- 필수 학습 · 삼각형 판별하기 JavaScript 풀이
- 필수 학습 · 연필 개수 JavaScript 풀이
- 필수 학습 · 1부터 N까지 합 출력하기 JavaScript 풀이
- 필수 학습 · 최솟값 구하기 JavaScript 풀이|배열 순회와 비교 갱신 원리
- 필수 학습 · 홀수 JavaScript 풀이: 조건 판별과 결과 처리 정리
- 필수 학습 · 10부제 JavaScript 풀이: 끝자리 비교로 위반 차량 수 세기
- 필수 학습 · A를 #으로 JavaScript 풀이: 문자열 순회와 치환
- 필수 학습 · 문자 찾기 JavaScript 풀이: 문자열 순회로 개수 세기
- 필수 학습 · 대문자 찾기 JavaScript 풀이
- 필수 학습 · 대문자로 통일 JavaScript 풀이
- 필수 학습 · 대소문자 변환 JavaScript 풀이
- 필수 학습 · 일곱 난쟁이 JavaScript 풀이: 두 명을 제외하는 완전탐색
- 필수 학습 · 코딩테스트 JS Map 풀이: 학급 회장 득표수 세기
- 필수 학습 · 코딩테스트 JS 스택 풀이: 올바른 괄호 검증하기
- 필수 학습 · 코딩테스트 JS 스택 풀이: 괄호문자 제거하기
- 필수 학습 · 코딩테스트 JS 스택 풀이: 크레인 인형뽑기 처리법
- 필수 학습 · 코딩테스트 JS 스택 풀이: 후위식 연산 계산하기
- 필수 학습 · 코딩테스트 JS 스택 풀이: 쇠막대기 레이저 절단 개수 세기
- 필수 학습 · 코딩테스트 JS 투 포인터 풀이: 두 정렬 배열 합치기
- 필수 학습 · 코딩테스트 JS 투 포인터 풀이: 공통 원소 추출하기
- 필수 학습 · 코딩테스트 JS 슬라이딩 윈도우 풀이: 최대 매출 구간 합 계산하기
- 필수 학습 · JavaScript 투 포인터: 합이 M인 연속 부분수열 개수
- 필수 학습 · 코딩테스트 JS 해시 풀이: 모든 아나그램 찾기
- 필수 학습 · 가장 긴 문자열 JavaScript 풀이
- 필수 학습 · 가운데 문자 출력 JavaScript 풀이
- 필수 학습 · 중복문자제거 JavaScript 풀이
- 필수 학습 · 코딩테스트 JS 고급: 최소 힙으로 다익스트라 최단 경로 구하기
- 필수 학습 · 코딩테스트 JS Union-Find: 연결 성분 수와 크기 구하기
- 필수 학습 · 코딩테스트 JS Trie: 접두사에 맞는 단어 수 세기
- 필수 학습 · 코딩테스트 JS Fenwick Tree: 값 갱신과 구간 합 처리
- 필수 학습 · 코딩테스트 JS 세그먼트 트리: 단일 대입과 구간 합
- 필수 학습 · 코딩테스트 JS LRU 캐시: 지도 타일 재사용 기록
- 필수 학습 · 코딩테스트 JS AVL 트리: 기준 이상 최솟값 찾기
- 필수 학습 · 코딩테스트 JS 큐: 상담 창구 대기열 명령 처리 현재 글
- 필수 학습 · 코딩테스트 JS 연결 리스트: 재생 대기 목록 관리
- 필수 학습 · JavaScript 원형 덱 연습: 최근 기록 창과 되돌리기
- 필수 학습 · JavaScript 해시 테이블 연습: 정규화 문자열 빈도와 등장 순서
- 필수 학습 · JavaScript 트리 순회 연습: 깊이별 노드 묶기
- 필수 학습 · JavaScript BST 연습: 닫힌 구간의 중복 키 보고서
- 필수 학습 · JavaScript 최소 힙 연습: 동률 순서를 지키는 작업 스케줄러
- 필수 학습 · JavaScript 그래프 연습: 연결 구역 크기를 작은 순서로 출력하기
- 필수 학습 · 중복단어제거 JavaScript 풀이
- 필수 학습 · TypeScript 이진 탐색 연습: 숫자 카드 존재 여부 확인
- 필수 학습 · 큰 수 출력하기 JavaScript 풀이
- 필수 학습 · 보이는 학생 JavaScript 풀이
- 필수 학습 · 가위바위보 JavaScript 풀이
- 필수 학습 · 점수계산 JavaScript 풀이
새 글 받아보기
RSS 리더에서 BlogFlow의 새 글을 확인할 수 있습니다.