정원이 30명인 놀이기구가 있다. 처음에는 아무도 없다. 정원 30은 상수로 두고, 지금 안에 있는 사람 수·지금까지 들여보낸 사람 수·돌려보낸 사람 수는 함수 밖에 둔 변수로 세어라. 명령마다 그 변수를 고치는 함수(in 처리, out 처리)를 불러 처리한다.
- in k: k명이 줄을 선다. 빈자리 수(30 − 안에 있는 수)와 k 중 작은 만큼만 들어가고, 나머지는 돌려보낸다. 들어간 사람 수를 출력한다.
- out k: k명이 나온다. 나온 뒤 안에 있는 사람 수를 출력한다.
모든 명령이 끝나면 지금까지 들여보낸 사람 수와 돌려보낸 사람 수를 빈칸 하나로 띄워 한 줄에 출력한다.
입력
첫 줄에 n(1 ≤ n ≤ 1000), 다음 n줄에 in k 또는 out k. in은 1 ≤ k ≤ 100, out은 1 ≤ k ≤ 그때 안에 있는 사람 수
출력
명령마다 한 줄, 마지막 줄에 "들여보낸 수 돌려보낸 수"
예시 1 · stdin
6
in 12
in 25
out 10
in 4
out 20
in 40
stdout
12
18
20
4
4
26
60 21
main.py
오류 목록00F8 ↓ · ⇧F8 ↑
입력(stdin)
실행하면 이 줄들이 차례로 input()·표준 입력으로 들어가요(실행 중에 묻지 않아요).
$ 준비됐어요
코드를 입력해 풀려면 PC에서 열어 주세요. 모바일에서는 문제와 풀이를 볼 수 있어요.
다른 언어로는?언어별 풀이 보기 · 8개 언어 풀이
상수 쓰는 법이 언어마다 달라요: Python은 CAPACITY = 30처럼 대문자로 이름만 짓고(바꿔도 막지 않아요, typing.Final은 검사 도구용), JS·TS const, Java static final int, C# const int, C #define CAPACITY 30(또는 const int, 다만 C에서는 배열 크기 같은 상수식이 아니에요), C++ constexpr int예요. 크레이콘에는 상수가 없어서 바꾸지 않기로 약속한 변수 정원 = 30;으로 둬요. 함수 밖 변수도 달라요: Java·C#은 클래스 밖에 변수를 둘 수 없어 static 필드로, C·C++은 파일 범위 전역 변수로, JS·TS는 바깥의 let으로 둬요. Python은 함수 안에서 읽기만 하면 바깥 변수가 보이지만, inside += a처럼 넣는 순간 지역 변수가 되어UnboundLocalError가 나요. 그래서 global inside를 먼저 적어요. 크레이콘은 맨 위에 만든 변수를 함수 안에서도 같은 변수로 써서 안 = 안 + a;가 바깥을 바꿔요. 다만 매개변수 이름을 들어가기(안, k)처럼 바깥 변수와 같게 지으면 함수 안의 안은 매개변수라서 바깥은 그대로예요. 흔한 함정 둘: 세는 값을 매개변수로 넘겨 함수 안에서 고치면 복사본만 바뀌고(C·Java·C#·JS·Python 모두 수는 값으로 넘겨요), 세는 변수를 반복문 안에서 만들면(for (...) { let inside = 0; ... }) 줄마다 0부터 다시 시작해요.
Pythonmain.py · 27 줄
CAPACITY = 30 # 상수: 대문자 이름은 '바꾸지 말자'는 약속일 뿐, Python이 막아 주지는 않는다inside = 0 # 함수 밖(모듈)에 있는 변수 — 모든 함수가 같이 쓴다admitted = 0turned_away = 0def enter(k): global inside, admitted, turned_away # 없으면 inside += ... 에서 UnboundLocalError a = min(k, CAPACITY - inside) # a는 이 함수 안에서만 있는 지역 변수 inside += a admitted += a turned_away += k - a return adef leave(k): global inside inside -= k return insiden = int(input())for _ in range(n): cmd, k = input().split() print(enter(int(k)) if cmd == "in" else leave(int(k)))print(admitted, turned_away)
JavaScriptmain.js · 28 줄
const lines = require("fs").readFileSync(0, "utf8").split("\n");const CAPACITY = 30; // const: 다시 넣으면 TypeErrorlet inside = 0; // 함수 밖의 let — 아래 함수들이 같이 쓴다let admitted = 0;let turnedAway = 0;function enter(k) { const a = Math.min(k, CAPACITY - inside); // 함수 안의 const는 이 함수에서만 보인다 inside += a; admitted += a; turnedAway += k - a; return a;}function leave(k) { inside -= k; return inside;}const n = Number(lines[0]);const out = [];for (let i = 1; i <= n; i++) { const [cmd, k] = lines[i].trim().split(" "); out.push(cmd === "in" ? enter(Number(k)) : leave(Number(k)));}out.push(`${admitted} ${turnedAway}`);console.log(out.join("\n"));
import java.io.BufferedReader;import java.io.InputStreamReader;import java.io.IOException;public class Main { static final int CAPACITY = 30; // final: 한 번 넣으면 못 바꾼다 static int inside = 0; // static 필드 — 모든 static 메서드가 같이 쓴다 static int admitted = 0; static int turnedAway = 0; static int enter(int k) { int a = Math.min(k, CAPACITY - inside); // 지역 변수 inside += a; admitted += a; turnedAway += k - a; return a; } static int leave(int k) { inside -= k; return inside; } public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int n = Integer.parseInt(br.readLine().trim()); StringBuilder out = new StringBuilder(); for (int i = 0; i < n; i++) { String[] parts = br.readLine().trim().split(" "); int k = Integer.parseInt(parts[1]); out.append(parts[0].equals("in") ? enter(k) : leave(k)).append('\n'); } out.append(admitted).append(' ').append(turnedAway).append('\n'); System.out.print(out); }}
C#Main.cs · 39 줄
using System;using System.Text;class Program{ const int Capacity = 30; // const: 컴파일할 때 값이 박힌다 static int inside = 0; // static 필드 — 클래스 안의 모든 메서드가 같이 쓴다 static int admitted = 0; static int turnedAway = 0; static int Enter(int k) { int a = Math.Min(k, Capacity - inside); inside += a; admitted += a; turnedAway += k - a; return a; } static int Leave(int k) { inside -= k; return inside; } static void Main() { int n = int.Parse(Console.ReadLine()); var out_ = new StringBuilder(); for (int i = 0; i < n; i++) { string[] parts = Console.ReadLine().Trim().Split(' '); int k = int.Parse(parts[1]); out_.Append(parts[0] == "in" ? Enter(k) : Leave(k)).Append('\n'); } out_.Append(admitted).Append(' ').Append(turnedAway).Append('\n'); Console.Write(out_); }}
C++main.cpp · 34 줄
#include <algorithm>#include <iostream>#include <string>constexpr int CAPACITY = 30; // constexpr: 컴파일할 때 정해지는 상수int inside = 0; // 전역 변수 — 아래 함수들이 같이 쓴다int admitted = 0;int turnedAway = 0;int enter(int k) { int a = std::min(k, CAPACITY - inside); inside += a; admitted += a; turnedAway += k - a; return a;}int leave(int k) { inside -= k; return inside;}int main() { int n; std::cin >> n; for (int i = 0; i < n; i++) { std::string cmd; int k; std::cin >> cmd >> k; std::cout << (cmd == "in" ? enter(k) : leave(k)) << '\n'; } std::cout << admitted << ' ' << turnedAway << '\n';}
Cmain.c · 34 줄
#include <stdio.h>#include <string.h>#define CAPACITY 30 /* 전처리기가 글자 그대로 30으로 바꿔 넣는다 */static int inside = 0; /* 파일 범위 변수: 이 파일의 모든 함수가 같이 쓴다 */static int admitted = 0;static int turned_away = 0;int enter(int k) { int room = CAPACITY - inside; int a = k < room ? k : room; inside += a; admitted += a; turned_away += k - a; return a;}int leave(int k) { inside -= k; return inside;}int main(void) { int n, k; char cmd[4]; scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%3s %d", cmd, &k); printf("%d\n", strcmp(cmd, "in") == 0 ? enter(k) : leave(k)); } printf("%d %d\n", admitted, turned_away); return 0;}
Craykonmain.cray · 37 줄
// 크레이콘에는 const가 없다: 바꾸지 않기로 약속한 변수로 둔다정원 = 30;안 = 0;들어간수 = 0;돌려보낸수 = 0;// 맨 위에 만든 변수는 함수 안에서도 같은 변수다(같이 쓴다)들어가기(k){ a = 수학.작은수(k, 정원 - 안); 안 = 안 + a; 들어간수 = 들어간수 + a; 돌려보낸수 = 돌려보낸수 + k - a; 돌려주기 a;}나가기(k){ 안 = 안 - k; 돌려주기 안;}n = 콘솔.줄읽기().수로변환();반복 (i = 0; i < n; i++){ parts = 콘솔.줄읽기().나누기(); k = parts[1].수로변환(); 만약 (parts[0] == "in") { 콘솔.쓰기(들어가기(k)); } 아니면 { 콘솔.쓰기(나가기(k)); }}콘솔.쓰기(들어간수 + " " + 돌려보낸수);