창구 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()·표준 입력으로 들어가요(실행 중에 묻지 않아요).
$ 준비됐어요
코드를 입력해 풀려면 PC에서 열어 주세요. 모바일에서는 문제와 풀이를 볼 수 있어요.
다른 언어로는?언어별 풀이 보기 · 6개 언어 풀이
이 문제는 클래스가 있는 Python·JavaScript·TypeScript·Java·C#·C++만 받아요(C에는 클래스가 없고, 크레이콘은 아직 클래스를 만들 수 없어요). 핵심은 "모든 객체가 함께 쓰는 값"과 "객체마다 따로인 값"을 가르는 거예요. 함께 쓰는 일련번호는 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'; }}