학교 현관에 우산 대여함이 있고, 처음에 우산 u개가 꽂혀 있다.
일 n개가 일어난 차례대로 주어진다.
want 이름은 그 이름의 사람이 우산을 빌리러 온 것이다. 대여함에 우산이 있으면 바로 하나를 빌려 가고, 없으면 기다리는 줄의 맨 뒤에 선다.
back은 빌려 간 우산 하나가 돌아온 것이다. 기다리는 사람이 있으면 그 가운데 가장 먼저 온 사람이 그 우산을 바로 받아 가고 줄을 떠난다. 기다리는 사람이 없으면 우산을 대여함에 꽂는다.
일마다 한 줄을 출력하라. 그 일로 누군가 우산을 받아 갔으면 그 사람의 이름을, 아무도 받아 가지 않았으면 -를 출력한다.
마지막 줄에는 아직 기다리는 사람의 수와 대여함에 꽂힌 우산의 수를 빈칸 하나로 띄워 출력하라.
입력
첫 줄에 n과 u가 빈칸 하나로 나뉘어 주어진다. 다음 n줄에 일이 한 줄에 하나씩 주어진다. 1 ≤ n ≤ 9,000, 0 ≤ u ≤ 9,000. 이름은 영어 소문자 1 ~ 10글자이고, 서로 다른 사람의 이름이 같을 수 있다. back은 빌려 가서 아직 돌아오지 않은 우산이 하나 이상 있을 때만 주어진다
출력
n + 1줄. 일마다 우산을 받아 간 사람의 이름 또는 -, 마지막 줄에 기다리는 사람의 수와 대여함의 우산 수
예시 1 · stdin
8 1
want mina
want joon
want sora
back
back
back
want hana
want dan
stdout
mina
-
-
joon
sora
-
hana
-
1 0
main.py
오류 목록00F8 ↓ · ⇧F8 ↑
입력(stdin)
실행하면 이 줄들이 차례로 input()·표준 입력으로 들어가요(실행 중에 묻지 않아요).
$ 준비됐어요
코드를 입력해 풀려면 PC에서 열어 주세요. 모바일에서는 문제와 풀이를 볼 수 있어요.
다른 언어로는?언어별 풀이 보기 · 8개 언어 풀이
큐(먼저 넣은 것이 먼저 나오는 줄)를 만드는 도구가 언어마다 달라요. Python은 collections.deque에 append로 넣고 popleft()로 꺼내요. Java는 ArrayDeque의 addLast·pollFirst, C#은 Queue<T>의 Enqueue·Dequeue, C++은 std::queue의 push·front·pop이에요. C++의 pop()은 값을 돌려주지 않아서 front()로 먼저 읽어야 해요. JS·TS와 C, 크레이콘에는 큐가 따로 없어서 배열(목록) 뒤에 넣고(JS push, 크레이콘 넣기) 맨 앞 자리를 가리키는 수 head만 하나씩 늘려요. 함정 하나: 맨 뒤에서 꺼내면(Python·JS pop()) 스택이 되어 가장 늦게 온 사람이 먼저 받아요. 예시의 첫 back에서 joon이 아니라 sora가 나와요. 함정 둘: 꺼내기 전에 줄이 비었는지 먼저 물어야 해요. 빈 줄에서 꺼낼 때 일어나는 일이 언어마다 달라요. Python popleft()는 IndexError로, C# Dequeue()는 InvalidOperationException으로 멈추고, Java pollFirst()는 null을, JS shift()는 오류 없이 undefined를 줘요. 그래서 JS에서는 예시의 셋째 back에 undefined가 찍히고, 우산이 대여함에 돌아오지 않아 hana도 받지 못해요. C++ front()는 빈 큐에서 무슨 일이 일어날지 정해져 있지 않고, 크레이콘은 빈 목록의 0번을 읽으면 오류로 멈춰요. 함정 셋: 돌아온 우산은 기다리던 사람에게 가거나 대여함에 꽂히거나 둘 중 하나예요. 대여함의 수를 늘려 놓고 기다리던 사람에게도 주면 우산이 하나 늘어나서, 예시의 dan이 없는 우산을 받아요.
Pythonmain.py · 23 줄
import sysfrom collections import dequelines = sys.stdin.read().split("\n")n, rack = map(int, lines[0].split())waiting = deque() # 기다리는 사람들: 뒤로 넣고 앞에서 꺼낸다out = []for line in lines[1:n + 1]: parts = line.split() if parts[0] == "want": if rack > 0: rack -= 1 out.append(parts[1]) else: waiting.append(parts[1]) out.append("-") elif waiting: out.append(waiting.popleft()) # 가장 먼저 온 사람이 받는다 else: rack += 1 # 기다리는 사람이 없으면 대여함에 꽂는다 out.append("-")out.append(f"{len(waiting)} {rack}")print("\n".join(out))
JavaScriptmain.js · 26 줄
const lines = require("fs").readFileSync(0, "utf8").split("\n");const [n, u] = lines[0].trim().split(" ").map(Number);let rack = u;// JS에는 큐가 따로 없다. 배열 뒤에 넣고, 맨 앞 자리(head)만 뒤로 옮긴다.const waiting = [];let head = 0;const out = [];for (let i = 1; i <= n; i++) { const [cmd, name] = lines[i].trim().split(" "); if (cmd === "want") { if (rack > 0) { rack--; out.push(name); } else { waiting.push(name); out.push("-"); } } else if (head < waiting.length) { out.push(waiting[head++]); // 가장 먼저 온 사람이 받는다 } else { rack++; // 기다리는 사람이 없으면 대여함에 꽂는다 out.push("-"); }}out.push(`${waiting.length - head} ${rack}`);console.log(out.join("\n"));
TypeScriptmain.ts · 28 줄
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const [n, u]: number[] = lines[0].trim().split(" ").map(Number);let rack: number = u;// TS에도 큐가 따로 없다. 배열 뒤에 넣고, 맨 앞 자리(head)만 뒤로 옮긴다.const waiting: string[] = [];let head = 0;const out: string[] = [];for (let i = 1; i <= n; i++) { const [cmd, name]: string[] = lines[i].trim().split(" "); if (cmd === "want") { if (rack > 0) { rack--; out.push(name); } else { waiting.push(name); out.push("-"); } } else if (head < waiting.length) { out.push(waiting[head++]); // 가장 먼저 온 사람이 받는다 } else { rack++; // 기다리는 사람이 없으면 대여함에 꽂는다 out.push("-"); }}out.push(`${waiting.length - head} ${rack}`);console.log(out.join("\n"));
JavaMain.java · 34 줄
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.ArrayDeque;public class Main { public static void main(String[] args) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); String[] first = in.readLine().trim().split(" "); int n = Integer.parseInt(first[0]); int rack = Integer.parseInt(first[1]); ArrayDeque<String> waiting = new ArrayDeque<>(); StringBuilder out = new StringBuilder(); for (int i = 0; i < n; i++) { String[] parts = in.readLine().trim().split(" "); if (parts[0].equals("want")) { if (rack > 0) { rack--; out.append(parts[1]).append('\n'); } else { waiting.addLast(parts[1]); out.append("-\n"); } } else if (!waiting.isEmpty()) { out.append(waiting.pollFirst()).append('\n'); // 가장 먼저 온 사람이 받는다 } else { rack++; // 기다리는 사람이 없으면 대여함에 꽂는다 out.append("-\n"); } } out.append(waiting.size()).append(' ').append(rack); System.out.println(out); }}
C#Main.cs · 43 줄
using System;using System.Collections.Generic;using System.Text;class Program{ static void Main() { string[] first = Console.ReadLine().Trim().Split(' '); int n = int.Parse(first[0]); int rack = int.Parse(first[1]); var waiting = new Queue<string>(); var sb = new StringBuilder(); for (int i = 0; i < n; i++) { string[] parts = Console.ReadLine().Trim().Split(' '); if (parts[0] == "want") { if (rack > 0) { rack--; sb.Append(parts[1]).Append('\n'); } else { waiting.Enqueue(parts[1]); sb.Append("-\n"); } } else if (waiting.Count > 0) { sb.Append(waiting.Dequeue()).Append('\n'); // 가장 먼저 온 사람이 받는다 } else { rack++; // 기다리는 사람이 없으면 대여함에 꽂는다 sb.Append("-\n"); } } sb.Append(waiting.Count).Append(' ').Append(rack).Append('\n'); Console.Write(sb); }}
C++main.cpp · 35 줄
#include <iostream>#include <queue>#include <string>using namespace std;int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, rack; cin >> n >> rack; queue<string> waiting; for (int i = 0; i < n; i++) { string cmd; cin >> cmd; if (cmd == "want") { string name; cin >> name; if (rack > 0) { rack--; cout << name << '\n'; } else { waiting.push(name); cout << "-\n"; } } else if (!waiting.empty()) { cout << waiting.front() << '\n'; // 가장 먼저 온 사람이 받는다 waiting.pop(); // pop()은 값을 돌려주지 않는다 } else { rack++; // 기다리는 사람이 없으면 대여함에 꽂는다 cout << "-\n"; } } cout << waiting.size() << ' ' << rack << '\n'; return 0;}
Cmain.c · 35 줄
#include <stdio.h>#include <string.h>#define MAXN 9000/* 배열로 만든 큐: tail 자리에 넣고 head 자리에서 꺼낸다. 기다리는 사람은 모두 합쳐 n명을 넘지 않으니 MAXN칸이면 된다. */static char waiting[MAXN][11];int main(void) { int n, rack; scanf("%d %d", &n, &rack); int head = 0, tail = 0; for (int i = 0; i < n; i++) { char cmd[8], name[11]; scanf("%7s", cmd); if (strcmp(cmd, "want") == 0) { scanf("%10s", name); if (rack > 0) { rack--; printf("%s\n", name); } else { strcpy(waiting[tail++], name); printf("-\n"); } } else if (head < tail) { printf("%s\n", waiting[head++]); /* 가장 먼저 온 사람이 받는다 */ } else { rack++; /* 기다리는 사람이 없으면 대여함에 꽂는다 */ printf("-\n"); } } printf("%d %d\n", tail - head, rack); return 0;}
Craykonmain.cray · 36 줄
첫줄 = 콘솔.수들읽기();n = 첫줄[0];rack = 첫줄[1];// 목록으로 만든 큐: 뒤에 넣고, 맨 앞 자리(head)만 뒤로 옮긴다waiting = [];head = 0;반복 (i = 0; i < n; i++){ parts = 콘솔.줄읽기().공백제거().나누기(); 만약 (parts[0] == "want") { 만약 (rack > 0) { rack -= 1; 콘솔.쓰기(parts[1]); } 아니면 { waiting.넣기(parts[1]); 콘솔.쓰기("-"); } } 아니면 만약 (head < waiting.개수) { // 가장 먼저 온 사람이 받는다 콘솔.쓰기(waiting[head]); head += 1; } 아니면 { // 기다리는 사람이 없으면 대여함에 꽂는다 rack += 1; 콘솔.쓰기("-"); }}콘솔.쓰기(waiting.개수 - head + " " + rack);