{ }codelper
목록 채워 만들기목록 번호목록에 넣기P0146

소극장 좌석 예약과 대기 줄

소극장에 1번부터 n번까지 좌석 n개가 있고, 처음에는 모두 비어 있다.
자리가 없을 때 기다리는 대기 줄도 있고, 처음에는 비어 있다.
첫 줄에 n과 명령 수 q가 주어지고, 다음 q줄에 명령이 하나씩 주어진다.
명령마다 결과를 한 줄에 출력한다. - "book 이름 k": 그 이름이 이미 좌석에 앉아 있거나 대기 줄에 있으면, 또는 k번 좌석이 차 있으면 아무것도 바꾸지 않고 0을 출력한다.
아니면 그 이름을 k번 좌석에 앉히고 k를 출력한다. - "any 이름": 그 이름이 이미 좌석에 앉아 있거나 대기 줄에 있으면 0을 출력한다.
아니면 빈 좌석 가운데 번호가 가장 작은 좌석에 앉히고 그 번호를 출력한다.
빈 좌석이 없으면 대기 줄 맨 뒤에 세우고, w 바로 뒤에 대기 줄에서의 순번(맨 앞이 1)을 붙여 출력한다(예: w3). - "cancel 이름": 그 이름이 좌석에 앉아 있으면 그 좌석을 비우고 좌석 번호를 출력한다.
이때 대기 줄에 사람이 있으면 맨 앞 사람이 대기 줄에서 빠져 그 좌석에 바로 앉는다.
그 이름이 대기 줄에 있으면 대기 줄에서 빼고, w 바로 뒤에 빠지기 전의 순번을 붙여 출력한다.
그 뒤의 사람들은 한 칸씩 앞당겨진다.
어디에도 없으면 0을 출력한다. - "where 이름": 그 이름이 앉은 좌석 번호를, 대기 중이면 w 바로 뒤에 지금 순번을 붙여, 어디에도 없으면 0을 출력한다. 명령을 모두 처리한 뒤 마지막 줄에 좌석 상태를 n글자로 출력한다.
i번째 글자는 i번 좌석이 차 있으면 '#', 비어 있으면 '.'이다.

입력
1 ≤ n ≤ 200, 1 ≤ q ≤ 2000, 1 ≤ k ≤ n.
이름은 영어 소문자·숫자 1 ~ 10글자.
명령과 이름, k는 빈칸 하나로 나뉜다
출력
q + 1줄.
명령마다 좌석 번호, w와 대기 순번, 또는 0 가운데 하나를 쓰고, 마지막 줄에 좌석 상태 n글자
예시 1 · stdin
3 9
book ann 2
any bob
any cy
any dan
any eve
where eve
cancel ann
where dan
cancel eve
stdout
2
1
3
w1
w2
w2
2
2
w1
###
main.py
입력(stdin)

실행하면 이 줄들이 차례로 input()·표준 입력으로 들어가요(실행 중에 묻지 않아요).

$ 준비됐어요

코드를 입력해 풀려면 PC에서 열어 주세요. 모바일에서는 문제와 풀이를 볼 수 있어요.

다른 언어로는?언어별 풀이 보기 · 8개 언어 풀이

좌석 목록을 빈 문자열 ""로 채워 만들고, 이름이 몇 번 칸에 있는지 자리를 찾는 문제예요.
0번 칸이 1번 좌석이라 출력할 때 1을 더해야 해요.
채워 만들기는 Python [""] * n, JS·TS new Array(n).fill(""), Java new ArrayList<>(Collections.nCopies(n, "")), C# Enumerable.Repeat("", n).ToList(), C++ std::vector<std::string> seats(n, ""), 크레이콘 새목록(n, "")이에요.
C는 char seats[200][11]의 칸마다 첫 글자를 '\0'로 둬서 빈 문자열을 만들어요.
함정 하나: JS new Array(n)만 하면 칸이 비어 있을 뿐 ""가 아니어서 seats[k - 1] === ""가 늘 거짓이에요.
Java new String[n]도 null로 차 있어서 equals를 부르면 NullPointerException이에요(C# new string[n]도 null이지만 ==는 null과 비교해도 멈추지 않아요).
자리 찾기는 Python index, JS·TS·Java indexOf, C# IndexOf, C++ std::find, 크레이콘 자리찾기예요.
함정 둘: 없는 값이면 다른 언어는 -1을 돌려주지만 Python index는 ValueError로 멈춰서 먼저 in으로 물어야 해요.
대기 줄 끝에 넣기는 Python append, JS·TS push, Java·C# add·Add, C++ push_back, 크레이콘 넣기이고, 맨 앞을 꺼내기는 Python pop(0), JS·TS shift(), Java remove(0), C# RemoveAt(0), 크레이콘 자리빼기(0)예요.
함정 셋: Python pop()은 맨 뒤 사람을 꺼내요.

Pythonmain.py · 49 줄
import sys lines = sys.stdin.read().split("\n")n, q = map(int, lines[0].split())seats = [""] * n   # 빈 자리는 "" — 0번 칸이 1번 자리waiting = []       # 대기 줄, 맨 앞이 0번out = [] for line in lines[1:q + 1]:    p = line.split()    cmd, name = p[0], p[1]    if cmd == "book" or cmd == "any":        if name in seats or name in waiting:            out.append("0")        elif cmd == "book":            k = int(p[2])            if seats[k - 1] == "":                seats[k - 1] = name                out.append(str(k))            else:                out.append("0")        elif "" in seats:            i = seats.index("")   # 가장 작은 번호의 빈 자리            seats[i] = name            out.append(str(i + 1))        else:            waiting.append(name)            out.append(f"w{len(waiting)}")    elif cmd == "cancel":        if name in seats:            i = seats.index(name)            seats[i] = waiting.pop(0) if waiting else ""   # 대기 맨 앞 사람이 바로 앉는다            out.append(str(i + 1))        elif name in waiting:            i = waiting.index(name)            waiting.pop(i)            out.append(f"w{i + 1}")        else:            out.append("0")    else:  # where        if name in seats:            out.append(str(seats.index(name) + 1))        elif name in waiting:            out.append(f"w{waiting.index(name) + 1}")        else:            out.append("0") out.append("".join("." if s == "" else "#" for s in seats))print("\n".join(out))
JavaScriptmain.js · 47 줄
const lines = require("fs").readFileSync(0, "utf8").split("\n");const [n, q] = lines[0].trim().split(" ").map(Number);const seats = new Array(n).fill(""); // 빈 자리는 "" — 0번 칸이 1번 자리const waiting = []; // 대기 줄, 맨 앞이 0번const out = []; for (const line of lines.slice(1, q + 1)) {  const [cmd, name, k] = line.trim().split(" ");  if (cmd === "book" || cmd === "any") {    if (seats.includes(name) || waiting.includes(name)) {      out.push("0");    } else if (cmd === "book") {      const at = Number(k) - 1;      if (seats[at] === "") {        seats[at] = name;        out.push(String(at + 1));      } else {        out.push("0");      }    } else if (seats.includes("")) {      const at = seats.indexOf(""); // 가장 작은 번호의 빈 자리      seats[at] = name;      out.push(String(at + 1));    } else {      waiting.push(name);      out.push(`w${waiting.length}`);    }  } else if (cmd === "cancel") {    const at = seats.indexOf(name);    const w = waiting.indexOf(name);    if (at !== -1) {      seats[at] = waiting.length > 0 ? waiting.shift() : ""; // 대기 맨 앞 사람이 바로 앉는다      out.push(String(at + 1));    } else if (w !== -1) {      waiting.splice(w, 1);      out.push(`w${w + 1}`);    } else {      out.push("0");    }  } else {    const at = seats.indexOf(name);    const w = waiting.indexOf(name);    out.push(at !== -1 ? String(at + 1) : w !== -1 ? `w${w + 1}` : "0");  }}out.push(seats.map((s) => (s === "" ? "." : "#")).join(""));console.log(out.join("\n"));
TypeScriptmain.ts · 48 줄
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const [n, q] = lines[0].trim().split(" ").map(Number);const seats: string[] = new Array<string>(n).fill(""); // 빈 자리는 "" — 0번 칸이 1번 자리const waiting: string[] = []; // 대기 줄, 맨 앞이 0번const out: string[] = []; for (const line of lines.slice(1, q + 1)) {  const [cmd, name, k] = line.trim().split(" ");  if (cmd === "book" || cmd === "any") {    if (seats.includes(name) || waiting.includes(name)) {      out.push("0");    } else if (cmd === "book") {      const at = Number(k) - 1;      if (seats[at] === "") {        seats[at] = name;        out.push(String(at + 1));      } else {        out.push("0");      }    } else if (seats.includes("")) {      const at = seats.indexOf(""); // 가장 작은 번호의 빈 자리      seats[at] = name;      out.push(String(at + 1));    } else {      waiting.push(name);      out.push(`w${waiting.length}`);    }  } else if (cmd === "cancel") {    const at = seats.indexOf(name);    const w = waiting.indexOf(name);    if (at !== -1) {      seats[at] = waiting.shift() ?? ""; // 대기 맨 앞 사람이 바로 앉는다(없으면 빈 자리)      out.push(String(at + 1));    } else if (w !== -1) {      waiting.splice(w, 1);      out.push(`w${w + 1}`);    } else {      out.push("0");    }  } else {    const at = seats.indexOf(name);    const w = waiting.indexOf(name);    out.push(at !== -1 ? String(at + 1) : w !== -1 ? `w${w + 1}` : "0");  }}out.push(seats.map((s) => (s === "" ? "." : "#")).join(""));console.log(out.join("\n"));
JavaMain.java · 56 줄
import java.io.*;import java.util.*; public class Main {    public static void main(String[] args) throws IOException {        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));        String[] first = br.readLine().trim().split(" ");        int n = Integer.parseInt(first[0]), q = Integer.parseInt(first[1]);        // 빈 자리는 "" — new String[n]은 null로 차니 nCopies로 ""를 채운다        List<String> seats = new ArrayList<>(Collections.nCopies(n, ""));        List<String> waiting = new ArrayList<>(); // 대기 줄, 맨 앞이 0번        StringBuilder out = new StringBuilder();         for (int t = 0; t < q; t++) {            String[] p = br.readLine().trim().split(" ");            String cmd = p[0], name = p[1];            int at = seats.indexOf(name), w = waiting.indexOf(name);            String res;            if (cmd.equals("book") || cmd.equals("any")) {                if (at != -1 || w != -1) {                    res = "0";                } else if (cmd.equals("book")) {                    int k = Integer.parseInt(p[2]);                    if (seats.get(k - 1).isEmpty()) {                        seats.set(k - 1, name);                        res = String.valueOf(k);                    } else {                        res = "0";                    }                } else if (seats.contains("")) {                    int free = seats.indexOf(""); // 가장 작은 번호의 빈 자리                    seats.set(free, name);                    res = String.valueOf(free + 1);                } else {                    waiting.add(name);                    res = "w" + waiting.size();                }            } else if (cmd.equals("cancel")) {                if (at != -1) {                    seats.set(at, waiting.isEmpty() ? "" : waiting.remove(0)); // 대기 맨 앞 사람이 바로 앉는다                    res = String.valueOf(at + 1);                } else if (w != -1) {                    waiting.remove(w); // int를 넘기면 자리로 뺀다                    res = "w" + (w + 1);                } else {                    res = "0";                }            } else {                res = at != -1 ? String.valueOf(at + 1) : w != -1 ? "w" + (w + 1) : "0";            }            out.append(res).append('\n');        }        for (String s : seats) out.append(s.isEmpty() ? '.' : '#');        System.out.println(out);    }}
C#Main.cs · 72 줄
using System;using System.Collections.Generic;using System.Linq;using System.Text; class Program{    static void Main()    {        int[] first = Console.ReadLine().Trim().Split(' ').Select(int.Parse).ToArray();        int n = first[0], q = first[1];        var seats = Enumerable.Repeat("", n).ToList(); // 빈 자리는 "" — 0번 칸이 1번 자리        var waiting = new List<string>();              // 대기 줄, 맨 앞이 0번        var sb = new StringBuilder();         for (int t = 0; t < q; t++)        {            string[] p = Console.ReadLine().Trim().Split(' ');            string cmd = p[0], name = p[1];            int at = seats.IndexOf(name), w = waiting.IndexOf(name);            string res;            if (cmd == "book" || cmd == "any")            {                if (at != -1 || w != -1) res = "0";                else if (cmd == "book")                {                    int k = int.Parse(p[2]);                    if (seats[k - 1] == "")                    {                        seats[k - 1] = name;                        res = k.ToString();                    }                    else res = "0";                }                else if (seats.Contains(""))                {                    int free = seats.IndexOf(""); // 가장 작은 번호의 빈 자리                    seats[free] = name;                    res = (free + 1).ToString();                }                else                {                    waiting.Add(name);                    res = "w" + waiting.Count;                }            }            else if (cmd == "cancel")            {                if (at != -1)                {                    seats[at] = "";                    if (waiting.Count > 0) // 대기 맨 앞 사람이 바로 앉는다                    {                        seats[at] = waiting[0];                        waiting.RemoveAt(0);                    }                    res = (at + 1).ToString();                }                else if (w != -1)                {                    waiting.RemoveAt(w);                    res = "w" + (w + 1);                }                else res = "0";            }            else res = at != -1 ? (at + 1).ToString() : w != -1 ? "w" + (w + 1) : "0";            sb.Append(res).Append('\n');        }        foreach (string s in seats) sb.Append(s == "" ? '.' : '#');        Console.WriteLine(sb);    }}
C++main.cpp · 64 줄
#include <algorithm>#include <iostream>#include <string>#include <vector> // 목록에서 처음 나오는 자리, 없으면 -1int index_of(const std::vector<std::string>& v, const std::string& x) {    auto it = std::find(v.begin(), v.end(), x);    return it == v.end() ? -1 : int(it - v.begin());} int main() {    int n, q;    std::cin >> n >> q;    std::vector<std::string> seats(n, ""); // 빈 자리는 "" — 0번 칸이 1번 자리    std::vector<std::string> waiting;      // 대기 줄, 맨 앞이 0번    std::string out;     for (int t = 0; t < q; t++) {        std::string cmd, name;        std::cin >> cmd >> name;        int at = index_of(seats, name), w = index_of(waiting, name);        std::string res;        if (cmd == "book" || cmd == "any") {            int k = 0;            if (cmd == "book") std::cin >> k; // 자리 번호는 book에만 있다            if (at != -1 || w != -1) {                res = "0";            } else if (cmd == "book") {                if (seats[k - 1].empty()) {                    seats[k - 1] = name;                    res = std::to_string(k);                } else {                    res = "0";                }            } else if (int free = index_of(seats, ""); free != -1) { // 가장 작은 번호의 빈 자리                seats[free] = name;                res = std::to_string(free + 1);            } else {                waiting.push_back(name);                res = "w" + std::to_string(waiting.size());            }        } else if (cmd == "cancel") {            if (at != -1) {                seats[at] = "";                if (!waiting.empty()) { // 대기 맨 앞 사람이 바로 앉는다                    seats[at] = waiting.front();                    waiting.erase(waiting.begin());                }                res = std::to_string(at + 1);            } else if (w != -1) {                waiting.erase(waiting.begin() + w);                res = "w" + std::to_string(w + 1);            } else {                res = "0";            }        } else {            res = at != -1 ? std::to_string(at + 1) : w != -1 ? "w" + std::to_string(w + 1) : "0";        }        out += res + "\n";    }    for (const auto& s : seats) out += s.empty() ? '.' : '#';    std::cout << out << "\n";}
Cmain.c · 78 줄
#include <stdio.h>#include <string.h> #define MAXN 200#define MAXQ 2000 static char seats[MAXN][11];   /* 빈 자리는 "" — 0번 칸이 1번 자리 */static char waiting[MAXQ][11]; /* 대기 줄, 맨 앞이 0번 */static int wait_count = 0; /* 이름 목록에서 처음 나오는 자리, 없으면 -1 */static int index_of(char list[][11], int count, const char *x) {    for (int i = 0; i < count; i++)        if (strcmp(list[i], x) == 0) return i;    return -1;} /* 대기 줄에서 i번을 빼고 뒤의 사람을 한 칸씩 당긴다 */static void remove_waiting(int i) {    memmove(waiting[i], waiting[i + 1], (size_t)(wait_count - i - 1) * sizeof waiting[0]);    wait_count--;} int main(void) {    int n, q;    scanf("%d %d", &n, &q);    for (int i = 0; i < n; i++) seats[i][0] = '\0'; /* 모든 자리를 빈 문자열로 채운다 */     for (int t = 0; t < q; t++) {        char cmd[8], name[11];        scanf("%7s %10s", cmd, name);        int at = index_of(seats, n, name), w = index_of(waiting, wait_count, name);        if (strcmp(cmd, "book") == 0 || strcmp(cmd, "any") == 0) {            int k = 0;            if (cmd[0] == 'b') scanf("%d", &k);            if (at != -1 || w != -1) {                puts("0");            } else if (cmd[0] == 'b') {                if (seats[k - 1][0] == '\0') {                    strcpy(seats[k - 1], name);                    printf("%d\n", k);                } else {                    puts("0");                }            } else {                int free = index_of(seats, n, ""); /* 가장 작은 번호의 빈 자리 */                if (free != -1) {                    strcpy(seats[free], name);                    printf("%d\n", free + 1);                } else {                    strcpy(waiting[wait_count++], name);                    printf("w%d\n", wait_count);                }            }        } else if (strcmp(cmd, "cancel") == 0) {            if (at != -1) {                seats[at][0] = '\0';                if (wait_count > 0) { /* 대기 맨 앞 사람이 바로 앉는다 */                    strcpy(seats[at], waiting[0]);                    remove_waiting(0);                }                printf("%d\n", at + 1);            } else if (w != -1) {                remove_waiting(w);                printf("w%d\n", w + 1);            } else {                puts("0");            }        } else {            if (at != -1) printf("%d\n", at + 1);            else if (w != -1) printf("w%d\n", w + 1);            else puts("0");        }    }    for (int i = 0; i < n; i++) putchar(seats[i][0] == '\0' ? '.' : '#');    putchar('\n');    return 0;}
Craykonmain.cray · 78 줄
first = 콘솔.줄읽기().공백제거().나누기();n = first[0].수로변환();q = first[1].수로변환();seats = 새목록(n, ""); // 빈 자리는 "" — 0번 칸이 1번 자리waiting = []; // 대기 줄, 맨 앞이 0번 반복 (t = 0; t < q; t++){    p = 콘솔.줄읽기().공백제거().나누기();    cmd = p[0];    name = p[1];    at = seats.자리찾기(name);    w = waiting.자리찾기(name);    res = "0";    만약 (cmd == "book" || cmd == "any")    {        만약 (at == -1 && w == -1)        {            만약 (cmd == "book")            {                k = p[2].수로변환();                만약 (seats[k - 1] == "")                {                    seats[k - 1] = name;                    res = "" + k;                }            }            아니면 만약 (seats.있나(""))            {                free = seats.자리찾기(""); // 가장 작은 번호의 빈 자리                seats[free] = name;                res = "" + (free + 1);            }            아니면            {                waiting.넣기(name);                res = "w" + waiting.개수;            }        }    }    아니면 만약 (cmd == "cancel")    {        만약 (at != -1)        {            seats[at] = "";            만약 (waiting.개수 > 0)            {                seats[at] = waiting[0];                waiting.자리빼기(0);            }            res = "" + (at + 1);        }        아니면 만약 (w != -1)        {            waiting.자리빼기(w);            res = "w" + (w + 1);        }    }    아니면    {        만약 (at != -1)        {            res = "" + (at + 1);        }        아니면 만약 (w != -1)        {            res = "w" + (w + 1);        }    }    콘솔.쓰기(res);} map = "";각각 (s 에서 seats){    map = map + (s == "" ? "." : "#");}콘솔.쓰기(map);