{ }codelper
큐P0351

먼저 온 사람부터 받는 우산 대여함

학교 현관에 우산 대여함이 있고, 처음에 우산 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
입력(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 deque lines = 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);