この問題はクラスのある Python・JavaScript・TypeScript・Java・C#・C++ だけを受け付けます(C にはクラスがなく、Craykon はまだクラスを作れません)。
一つ目の落とし穴は拒否の境界です:残高と同じ金額は引き出せるので amount > balance のときだけ拒否し、>= と書くと間違いです。
二つ目は残高の大きさです:一つの口座に 10 億ずつ 5000 回入れると約 5 兆になり、Java int・C# int・C++ int(約 21 億まで)は黙ってあふれます。
Java・C# は long、C++ は long long を使います。
Python int は上限がなく、JS・TS number は 2^53 まで正確なので大丈夫です。
三つ目はオブジェクトを取り出すときにコピーができるかどうかです。
Python・JS・TS・Java のオブジェクトと C# の class は参照で扱われるので、辞書から取り出した口座を変えると元の口座が変わります。
しかし C++ の Account acc = accounts[i]; はオブジェクトを丸ごとコピーするので Account& acc のように参照で受け取る必要があり、C# で class の代わりに struct にすると値型なので取り出すたびにコピーが返り、入金が消えます。
振替は withdraw が成功したときだけ deposit するようにメソッド同士を呼べば、拒否の規則を一か所にだけ書けます。
Pythonmain.py · 47 行import sys class Account: def __init__(self, name, balance): self.name = name self.balance = balance self.refused = 0 def deposit(self, amount): self.balance += amount def withdraw(self, amount): """잔액이 모자라면 거절하고 False를 돌려준다.""" if amount > self.balance: self.refused += 1 return False self.balance -= amount return True def transfer(self, other, amount): if self.withdraw(amount): other.deposit(amount) lines = sys.stdin.read().split("\n")n = int(lines[0])accounts = []by_name = {}for line in lines[1:n + 1]: name, balance = line.split() acc = Account(name, int(balance)) accounts.append(acc) by_name[name] = acc q = int(lines[n + 1])for line in lines[n + 2:n + 2 + q]: p = line.split() if p[0] == "deposit": by_name[p[1]].deposit(int(p[2])) elif p[0] == "withdraw": by_name[p[1]].withdraw(int(p[2])) else: by_name[p[1]].transfer(by_name[p[2]], int(p[3])) for acc in accounts: print(acc.name, acc.balance, acc.refused)
JavaScriptmain.js · 46 行class Account { constructor(name, balance) { this.name = name; this.balance = balance; this.refused = 0; } deposit(amount) { this.balance += amount; } // 잔액이 모자라면 거절하고 false를 돌려준다 withdraw(amount) { if (amount > this.balance) { this.refused++; return false; } this.balance -= amount; return true; } transfer(other, amount) { if (this.withdraw(amount)) other.deposit(amount); }} const lines = require("fs").readFileSync(0, "utf8").split("\n");const n = Number(lines[0]);const accounts = [];const byName = new Map();for (let i = 1; i <= n; i++) { const [name, balance] = lines[i].trim().split(" "); const acc = new Account(name, Number(balance)); accounts.push(acc); byName.set(name, acc);} const q = Number(lines[n + 1]);for (let i = n + 2; i < n + 2 + q; i++) { const p = lines[i].trim().split(" "); if (p[0] === "deposit") byName.get(p[1]).deposit(Number(p[2])); else if (p[0] === "withdraw") byName.get(p[1]).withdraw(Number(p[2])); else byName.get(p[1]).transfer(byName.get(p[2]), Number(p[3]));} console.log(accounts.map((a) => `${a.name} ${a.balance} ${a.refused}`).join("\n"));
TypeScriptmain.ts · 56 行import { readFileSync } from "node:fs"; class Account { readonly name: string; private balance: number; private refused = 0; constructor(name: string, balance: number) { this.name = name; this.balance = balance; } deposit(amount: number): void { this.balance += amount; } // 잔액이 모자라면 거절하고 false를 돌려준다 withdraw(amount: number): boolean { if (amount > this.balance) { this.refused++; return false; } this.balance -= amount; return true; } transfer(other: Account, amount: number): void { if (this.withdraw(amount)) other.deposit(amount); } describe(): string { return `${this.name} ${this.balance} ${this.refused}`; }} const lines: string[] = readFileSync(0, "utf8").split("\n");const n: number = Number(lines[0]);const accounts: Account[] = [];const byName = new Map<string, Account>();for (let i = 1; i <= n; i++) { const [name, balance] = lines[i].trim().split(" "); const acc = new Account(name, Number(balance)); accounts.push(acc); byName.set(name, acc);} const q: number = Number(lines[n + 1]);for (let i = n + 2; i < n + 2 + q; i++) { const p: string[] = lines[i].trim().split(" "); const acc = byName.get(p[1])!; if (p[0] === "deposit") acc.deposit(Number(p[2])); else if (p[0] === "withdraw") acc.withdraw(Number(p[2])); else acc.transfer(byName.get(p[2])!, Number(p[3]));} console.log(accounts.map((a) => a.describe()).join("\n"));
JavaMain.java · 66 行import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map; class Account { private final String name; private long balance; // 5000번 넣으면 int(약 21억)를 넘는다 private int refused = 0; Account(String name, long balance) { this.name = name; this.balance = balance; } void deposit(long amount) { balance += amount; } /** 잔액이 모자라면 거절하고 false를 돌려준다. */ boolean withdraw(long amount) { if (amount > balance) { refused++; return false; } balance -= amount; return true; } void transfer(Account other, long amount) { if (withdraw(amount)) other.deposit(amount); } String describe() { return name + " " + balance + " " + refused; }} public class Main { public static void main(String[] args) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); int n = Integer.parseInt(in.readLine().trim()); List<Account> accounts = new ArrayList<>(); Map<String, Account> byName = new HashMap<>(); for (int i = 0; i < n; i++) { String[] p = in.readLine().trim().split(" "); Account acc = new Account(p[0], Long.parseLong(p[1])); accounts.add(acc); byName.put(p[0], acc); } int q = Integer.parseInt(in.readLine().trim()); for (int i = 0; i < q; i++) { String[] p = in.readLine().trim().split(" "); Account acc = byName.get(p[1]); switch (p[0]) { case "deposit" -> acc.deposit(Long.parseLong(p[2])); case "withdraw" -> acc.withdraw(Long.parseLong(p[2])); default -> acc.transfer(byName.get(p[2]), Long.parseLong(p[3])); } } StringBuilder out = new StringBuilder(); for (Account acc : accounts) out.append(acc.describe()).append('\n'); System.out.print(out); }}
C#Main.cs · 69 行using System;using System.Collections.Generic;using System.Text; class Account{ public string Name { get; } public long Balance { get; private set; } // 5000번 넣으면 int(약 21억)를 넘는다 public int Refused { get; private set; } public Account(string name, long balance) { Name = name; Balance = balance; } public void Deposit(long amount) => Balance += amount; // 잔액이 모자라면 거절하고 false를 돌려준다 public bool Withdraw(long amount) { if (amount > Balance) { Refused++; return false; } Balance -= amount; return true; } public void Transfer(Account other, long amount) { if (Withdraw(amount)) other.Deposit(amount); }} class Program{ static void Main() { int n = int.Parse(Console.ReadLine()); var accounts = new List<Account>(); var byName = new Dictionary<string, Account>(); for (int i = 0; i < n; i++) { string[] p = Console.ReadLine().Trim().Split(' '); var acc = new Account(p[0], long.Parse(p[1])); accounts.Add(acc); byName[p[0]] = acc; } int q = int.Parse(Console.ReadLine()); for (int i = 0; i < q; i++) { string[] p = Console.ReadLine().Trim().Split(' '); Account acc = byName[p[1]]; switch (p[0]) { case "deposit": acc.Deposit(long.Parse(p[2])); break; case "withdraw": acc.Withdraw(long.Parse(p[2])); break; default: acc.Transfer(byName[p[2]], long.Parse(p[3])); break; } } var sb = new StringBuilder(); foreach (var acc in accounts) sb.Append($"{acc.Name} {acc.Balance} {acc.Refused}\n"); Console.Write(sb); }}
C++main.cpp · 68 行#include <iostream>#include <string>#include <unordered_map>#include <utility>#include <vector> class Account {public: Account(std::string name, long long balance) : name_(std::move(name)), balance_(balance) {} void deposit(long long amount) { balance_ += amount; } // 잔액이 모자라면 거절하고 false를 돌려준다 bool withdraw(long long amount) { if (amount > balance_) { refused_++; return false; } balance_ -= amount; return true; } void transfer(Account& other, long long amount) { if (withdraw(amount)) other.deposit(amount); } void print() const { std::cout << name_ << ' ' << balance_ << ' ' << refused_ << '\n'; } private: std::string name_; long long balance_; // 5000번 넣으면 int(약 21억)를 넘는다 int refused_ = 0;}; int main() { std::ios::sync_with_stdio(false); int n; std::cin >> n; std::vector<Account> accounts; std::unordered_map<std::string, int> index; // 이름 → 자리(벡터가 자라도 바뀌지 않는다) for (int i = 0; i < n; i++) { std::string name; long long balance; std::cin >> name >> balance; accounts.emplace_back(name, balance); index[name] = i; } int q; std::cin >> q; for (int i = 0; i < q; i++) { std::string cmd, a; long long x; std::cin >> cmd >> a; Account& acc = accounts[index[a]]; // &를 빼면 복사본이 바뀐다 if (cmd == "transfer") { std::string b; std::cin >> b >> x; acc.transfer(accounts[index[b]], x); } else { std::cin >> x; if (cmd == "deposit") acc.deposit(x); else acc.withdraw(x); } } for (const Account& acc : accounts) acc.print();}