{ }codelper
常量作用域声明变量P0086

游乐设施的限员

有一个最多容纳 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
输入(stdin)

运行时这些行会依次作为 input()/标准输入传入(运行中不会等待输入)。

$ 就绪

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

其他语言怎么写?查看各语言题解 · 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。
Craykon 没有常量,所以用约定不改的变量 限员 = 30;。
函数外的变量也不同:Java、C# 不能在类外放变量,所以用 static 字段;C、C++ 用文件作用域的全局变量;JS/TS 用外层的 let。
Python 在函数里只读的话能看到外层变量,但像 inside += a 这样一赋值它就变成局部变量,会出现 UnboundLocalError,所以先写 global inside。
Craykon 把最上层创建的变量在函数里也当作同一个变量,所以 里面 = 里面 + a; 会改到外层;但如果像 进入(里面, k) 这样让参数和外层变量同名,函数里的 里面 就是参数,外层保持不变。
两个常见陷阱:把计数值作为参数传进去在函数里修改,只会改到副本(C、Java、C#、JS、Python 都是按值传数字);在循环里创建计数变量(for (...) { let inside = 0; ... })则每行都从 0 重新开始。

Pythonmain.py · 27 行
CAPACITY = 30  # 상수: 대문자 이름은 '바꾸지 말자'는 약속일 뿐, Python이 막아 주지는 않는다 inside = 0       # 함수 밖(모듈)에 있는 변수 — 모든 함수가 같이 쓴다admitted = 0turned_away = 0  def enter(k):    global inside, admitted, turned_away  # 없으면 inside += ... 에서 UnboundLocalError    a = min(k, CAPACITY - inside)  # a는 이 함수 안에서만 있는 지역 변수    inside += a    admitted += a    turned_away += k - a    return a  def leave(k):    global inside    inside -= k    return inside  n = 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"));
TypeScriptmain.ts · 29 行
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n"); const CAPACITY = 30; // 타입은 리터럴 30 — 다시 넣으면 컴파일 오류let inside = 0;let admitted = 0;let turnedAway = 0; function enter(k: number): number {  const a: number = Math.min(k, CAPACITY - inside);  inside += a;  admitted += a;  turnedAway += k - a;  return a;} function leave(k: number): number {  inside -= k;  return inside;} const n: number = Number(lines[0]);const out: (number | string)[] = [];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"));
JavaMain.java · 36 行
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));    }}控制台.输出(들어간수 + " " + 돌려보낸수);