用窗口类来模拟一个有 m 个窗口的店。 号码牌的流水号是所有窗口共用的一个值,所以在类里只放一个(类变量、静态字段),而每个窗口领到的号码牌列表由各窗口对象分别持有。 窗口是编号 1 到 m 的 m 个不同对象。 第一行给出 m 和命令数 q,接下来 q 行每行一个命令。"take w":流水号加 1(第一张为 1),把这张号码牌放到窗口 w 列表的末尾,输出 "流水号 列表长度"(列表长度是放入后窗口 w 列表中的号码牌数)。"reset w":只清空窗口 w 的列表。 其他窗口和流水号保持不变。 没有输出。"show w":在一行中先输出窗口 w 列表中的号码牌数,再按放入顺序输出列表中的流水号,用一个空格分隔(为空时只输出 0)。
输入
1 ≤ m ≤ 100,1 ≤ q ≤ 5000,1 ≤ w ≤ m
输出
每个 take 和 show 命令输出一行
样例 1 · stdin
3 9
take 1
take 2
take 1
show 1
reset 1
show 1
take 1
show 1
show 3
stdout
1 1
2 1
3 2
2 1 3
0
4 1
1 4
0
main.py
错误列表00F8 ↓ · ⇧F8 ↑
输入(stdin)
运行时这些行会依次作为 input()/标准输入传入(运行中不会等待输入)。
$ 就绪
请在电脑上打开以编写和运行代码。在手机上可以查看题目和题解。
其他语言怎么写?查看各语言题解 · 6 种语言题解
本题只接受有类的 Python、JavaScript、TypeScript、Java、C#、C++(C 没有类,Craykon 还不能定义类)。 关键是区分"所有对象共用的值"和"每个对象各自的值"。 共用的流水号在 Java、C# 中是 static int,JS、TS 中是 static lastSerial = 0,C++ 中是 inline static int(C++17;没有 inline 就要在类外另写定义 int Window::lastSerial = 0;),Python 中是类体里的 last_serial = 0。 有三个陷阱。 Python 的 self.last_serial += 1 不会改变类变量,而是只在该对象上新建一个同名的值,于是每个窗口各自计数。 请用类名修改:Window.last_serial += 1。 反过来,把 served = [] 放在类体里,所有窗口就共用一个列表。 每个对象各自的列表要在 __init__ 中用 self.served = [] 创建。 JS 中用 this.lastSerial 读取静态字段会因为对象上没有它而得到 undefined,结果变成 NaN(TS 会用编译错误挡住)。 最后,创建 m 个对象时,Python 的 [Window()] * m 和 JS 的 Array(m).fill(new Window()) 让 m 个格子指向同一个对象。 请每格新建一个,如 Python [Window() for _ in range(m)]、JS Array.from({ length: m }, () => new Window())。 C++ 的 std::vector<Window> windows(m) 按值分别创建 m 个,没有问题。
Pythonmain.py · 35 行
import sysclass Window: last_serial = 0 # 클래스 변수: 모든 창구가 하나를 함께 쓴다 def __init__(self): self.served = [] # 객체마다 따로 갖는 목록(여기서 만들어야 한다) def take(self): Window.last_serial += 1 # self.last_serial += 1 이면 이 창구만의 값이 새로 생긴다 self.served.append(Window.last_serial) return Window.last_serial, len(self.served) def reset(self): self.served = [] def show(self): return " ".join(map(str, [len(self.served)] + self.served))data = sys.stdin.read().split()m, q = int(data[0]), int(data[1])windows = [Window() for _ in range(m)]out = []for i in range(q): cmd, w = data[2 + 2 * i], windows[int(data[3 + 2 * i]) - 1] if cmd == "take": serial, local = w.take() out.append(f"{serial} {local}") elif cmd == "reset": w.reset() else: out.append(w.show())print("\n".join(out))
JavaScriptmain.js · 35 行
class Window { static lastSerial = 0; // 정적 필드: 모든 창구가 하나를 함께 쓴다 constructor() { this.served = []; // 객체마다 따로 갖는 목록 } take() { Window.lastSerial++; // this.lastSerial 은 객체에 없어서 undefined this.served.push(Window.lastSerial); return `${Window.lastSerial} ${this.served.length}`; } reset() { this.served = []; } show() { return [this.served.length, ...this.served].join(" "); }}const data = require("fs").readFileSync(0, "utf8").trim().split(/\s+/);const m = Number(data[0]);const q = Number(data[1]);const windows = Array.from({ length: m }, () => new Window());const out = [];for (let i = 0; i < q; i++) { const cmd = data[2 + 2 * i]; const w = windows[Number(data[3 + 2 * i]) - 1]; if (cmd === "take") out.push(w.take()); else if (cmd === "reset") w.reset(); else out.push(w.show());}console.log(out.join("\n"));
TypeScriptmain.ts · 34 行
import { readFileSync } from "node:fs";class Window { private static lastSerial = 0; // 정적 필드: 모든 창구가 하나를 함께 쓴다 private served: number[] = []; // 객체마다 따로 갖는 목록 take(): string { Window.lastSerial++; this.served.push(Window.lastSerial); return `${Window.lastSerial} ${this.served.length}`; } reset(): void { this.served = []; } show(): string { return [this.served.length, ...this.served].join(" "); }}const data: string[] = readFileSync(0, "utf8").trim().split(/\s+/);const m: number = Number(data[0]);const q: number = Number(data[1]);const windows: Window[] = Array.from({ length: m }, () => new Window());const out: string[] = [];for (let i = 0; i < q; i++) { const cmd = data[2 + 2 * i]; const w = windows[Number(data[3 + 2 * i]) - 1]; if (cmd === "take") out.push(w.take()); else if (cmd === "reset") w.reset(); else out.push(w.show());}console.log(out.join("\n"));
JavaMain.java · 49 行
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.ArrayList;import java.util.List;import java.util.StringTokenizer;class Window { private static int lastSerial = 0; // static: 모든 창구가 하나를 함께 쓴다 private List<Integer> served = new ArrayList<>(); // 객체마다 따로 String take() { lastSerial++; served.add(lastSerial); return lastSerial + " " + served.size(); } void reset() { served = new ArrayList<>(); } String show() { StringBuilder sb = new StringBuilder().append(served.size()); for (int s : served) sb.append(' ').append(s); return sb.toString(); }}public class Main { public static void main(String[] args) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(in.readLine()); int m = Integer.parseInt(st.nextToken()); int q = Integer.parseInt(st.nextToken()); Window[] windows = new Window[m]; for (int i = 0; i < m; i++) windows[i] = new Window(); StringBuilder out = new StringBuilder(); for (int i = 0; i < q; i++) { st = new StringTokenizer(in.readLine()); String cmd = st.nextToken(); Window w = windows[Integer.parseInt(st.nextToken()) - 1]; switch (cmd) { case "take" -> out.append(w.take()).append('\n'); case "reset" -> w.reset(); default -> out.append(w.show()).append('\n'); } } System.out.print(out); }}
C#Main.cs · 45 行
using System;using System.Collections.Generic;using System.Text;class Window{ private static int lastSerial = 0; // static: 모든 창구가 하나를 함께 쓴다 private List<int> served = new List<int>(); // 객체마다 따로 public string Take() { lastSerial++; served.Add(lastSerial); return $"{lastSerial} {served.Count}"; } public void Reset() => served = new List<int>(); public string Show() => served.Count == 0 ? "0" : $"{served.Count} {string.Join(" ", served)}";}class Program{ static void Main() { string[] first = Console.ReadLine().Split(' '); int m = int.Parse(first[0]), q = int.Parse(first[1]); var windows = new Window[m]; for (int i = 0; i < m; i++) windows[i] = new Window(); var sb = new StringBuilder(); for (int i = 0; i < q; i++) { string[] p = Console.ReadLine().Trim().Split(' '); Window w = windows[int.Parse(p[1]) - 1]; switch (p[0]) { case "take": sb.Append(w.Take()).Append('\n'); break; case "reset": w.Reset(); break; default: sb.Append(w.Show()).Append('\n'); break; } } Console.Write(sb); }}
C++main.cpp · 40 行
#include <iostream>#include <string>#include <vector>class Window {public: std::string take() { lastSerial++; served_.push_back(lastSerial); return std::to_string(lastSerial) + " " + std::to_string(served_.size()); } void reset() { served_.clear(); } std::string show() const { std::string s = std::to_string(served_.size()); for (int x : served_) s += " " + std::to_string(x); return s; }private: inline static int lastSerial = 0; // static: 모든 창구가 하나를 함께 쓴다(inline 없으면 클래스 밖에 정의가 필요) std::vector<int> served_; // 객체마다 따로};int main() { std::ios::sync_with_stdio(false); int m, q; std::cin >> m >> q; std::vector<Window> windows(m); // 서로 다른 Window 객체 m개 for (int i = 0; i < q; i++) { std::string cmd; int w; std::cin >> cmd >> w; Window& win = windows[w - 1]; if (cmd == "take") std::cout << win.take() << '\n'; else if (cmd == "reset") win.reset(); else std::cout << win.show() << '\n'; }}