{ }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);