{ }codelper
클래스메서드P0078

은행 계좌 객체

계좌를 클래스로 만들어라.
계좌 객체는 이름, 잔액, 거절된 횟수를 필드로 갖고, 입금(deposit)·출금(withdraw)·이체(transfer) 메서드로만 잔액을 바꾼다.
첫 줄에 계좌 수 n, 다음 n줄에 "이름 처음잔액", 그다음 줄에 명령 수 q, 다음 q줄에 명령이 하나씩 주어진다.
명령은 세 가지다: "deposit 이름 x"는 그 계좌에 x를 넣는다.
"withdraw 이름 x"는 그 계좌에서 x를 꺼낸다.
"transfer 보내는이름 받는이름 x"는 보내는 계좌에서 x를 꺼내 받는 계좌에 넣는다.
꺼낼 금액 x가 잔액보다 크면 그 출금·이체는 거절되어 어느 계좌의 잔액도 바뀌지 않고, 꺼내려던 계좌(이체면 보내는 계좌)의 거절 횟수만 1 늘어난다.
잔액과 x가 같으면 거절하지 않는다(잔액이 0이 된다).
모든 명령을 차례로 처리한 뒤, 계좌마다 "이름 잔액 거절횟수"를 입력에 나온 계좌 차례대로 한 줄씩 출력하라.

입력
1 ≤ n ≤ 1000, 1 ≤ q ≤ 5000.
이름은 영어 소문자·숫자 1 ~ 10글자이고 서로 다르다.
0 ≤ 처음잔액 ≤ 1,000,000,000, 1 ≤ x ≤ 1,000,000,000(정수).
명령의 이름은 모두 있는 계좌이고, 이체의 두 이름은 서로 다르다
출력
n줄, 줄마다 이름·잔액·거절횟수를 빈칸 하나로(잔액은 최대 약 5조까지 커진다)
예시 1 · stdin
3
mina 100
jun 50
seo 0
5
withdraw mina 100
transfer jun seo 30
withdraw jun 21
deposit mina 7
transfer seo mina 31
stdout
mina 7 0
jun 20 1
seo 30 1
main.py
입력(stdin)

실행하면 이 줄들이 차례로 input()·표준 입력으로 들어가요(실행 중에 묻지 않아요).

$ 준비됐어요

코드를 입력해 풀려면 PC에서 열어 주세요. 모바일에서는 문제와 풀이를 볼 수 있어요.

다른 언어로는?언어별 풀이 보기 · 6개 언어 풀이

이 문제는 클래스가 있는 Python·JavaScript·TypeScript·Java·C#·C++만 받아요(C에는 클래스가 없고, 크레이콘은 아직 클래스를 만들 수 없어요).
첫째 함정은 거절 경계예요: 잔액과 같은 금액은 꺼낼 수 있으니 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();}