{ }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()/标准输入传入(运行中不会等待输入)。

$ 就绪

请在电脑上打开以编写和运行代码。在手机上可以查看题目和题解。

其他语言怎么写?查看各语言题解 · 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, ""),Craykon 新列表(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,Craykon 查找位置(韩语 자리찾기)。
陷阱二:值不存在时其他语言返回 -1,而 Python 的 index 会抛 ValueError 停下,所以要先用 in 判断。
在队尾添加:Python append,JS/TS push,Java/C# add/Add,C++ push_back,Craykon 添加(韩语 넣기);取出队首:Python pop(0),JS/TS shift(),Java remove(0),C# RemoveAt(0),Craykon 按位置移除(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);