{ }codelper
거꾸로 반복겹친 조건참·거짓P0127

자판기 거스름돈

자판기가 손님에게 거스름돈을 내준다. 동전은 10원, 50원, 100원, 500원 네 가지다. 첫 줄에 자판기에 든 10원, 50원, 100원, 500원 동전의 개수가 이 차례로 주어진다. 둘째 줄에 손님 수 q가 주어지고, 다음 q줄에 손님마다 물건값 p와 넣은 돈 m이 주어진다. 손님이 넣은 돈은 따로 모이므로 거스름돈으로 쓰지 않는다. 손님을 차례로 처리하며 손님마다 한 줄을 출력하라. m이 p보다 작으면 "금액 부족"를 출력한다. 그 밖에는 거스름돈 c = m - p를 500원, 100원, 50원, 10원 차례로 맞춘다. 동전마다 남은 금액을 넘지 않고 자판기에 남은 개수를 넘지 않는 한 최대한 많이 쓴다. 이렇게 해서 c를 정확히 맞추면 500원, 100원, 50원, 10원 동전을 몇 개 썼는지 이 차례로 빈칸 하나씩 띄워 출력하고, 쓴 동전을 자판기에서 뺀다. c가 0이면 "0 0 0 0"이 된다. 이렇게 해서 c를 정확히 맞추지 못하면 "거스름돈 없음"를 출력하고, 자판기의 동전은 그대로 둔다.

입력
동전 개수는 각각 0 이상 1000 이하, 1 ≤ q ≤ 100, 10 ≤ p ≤ 10000, 0 ≤ m ≤ 50000, p와 m은 10의 배수
출력
손님마다 한 줄: 동전 개수 넷, "금액 부족", 또는 "거스름돈 없음"
예시 1 · stdin
5 2 3 1
5
120 1000
430 500
290 300
600 500
1000 1000
stdout
1 3 1 3
0 0 1 2
거스름돈 없음
금액 부족
0 0 0 0
main.py
입력(stdin)

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

$ 준비됐어요

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

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

입력은 작은 동전부터, 계산과 출력은 큰 동전부터예요.
그래서 배열을 뒤에서 앞으로 돌아요: Python range(3, -1, -1)(끝 -1은 들어가지 않아서 0까지 돎), C 계열·JS·TS for (i = 3; i >= 0; i--), 크레이콘 반복 (i = 3; i >= 0; i--).
작은 동전부터 돌면 10원을 잔뜩 내주는 틀린 답이 나와요.
쓸 개수는 min(남은 금액 / 동전, 남은 개수)예요.
정수 몫은 Python //, JS·TS Math.floor(a / b), 크레이콘 수학.몫(a, b)이고, Java·C#·C·C++는 int끼리 /면 몫이에요.
남은 개수를 빼먹거나, 쓰는 동시에 자판기에서 빼서 실패한 손님 때 동전이 사라지게 하는 것이 흔한 실수예요.
먼저 셈만 하고 ok = left == 0이라는 참거짓 값으로 성공을 확인한 뒤에 빼요.
참거짓 타입은 Python bool(True/False), Java boolean, C# bool, C++ bool, C는 <stdbool.h>의 bool(C23부터는 헤더 없이), JS·TS boolean, 크레이콘 참/거짓이에요.
10·50·100·500원은 작은 동전이 큰 동전을 나누어떨어뜨리므로, 이렇게 큰 것부터 쓰는 방법이 맞출 수 있는 금액을 놓치지 않아요.

Pythonmain.py · 21 줄
COINS = [10, 50, 100, 500]stock = list(map(int, input().split()))q = int(input())for _ in range(q):    p, m = map(int, input().split())    if m < p:        print("금액 부족")    else:        left = m - p        used = [0, 0, 0, 0]        # 큰 동전부터: 자리 3(500원)에서 0(10원)으로 거꾸로        for i in range(3, -1, -1):            used[i] = min(left // COINS[i], stock[i])            left -= used[i] * COINS[i]        ok = left == 0        if ok:            for i in range(4):                stock[i] -= used[i]            print(used[3], used[2], used[1], used[0])        else:            print("거스름돈 없음")  # 자판기 동전은 건드리지 않았다
JavaScriptmain.js · 27 줄
const lines = require("fs").readFileSync(0, "utf8").split("\n");const COINS = [10, 50, 100, 500];const stock = lines[0].trim().split(/\s+/).map(Number);const q = Number(lines[1]);const out = [];for (let t = 0; t < q; t++) {  const [p, m] = lines[2 + t].trim().split(/\s+/).map(Number);  if (m < p) {    out.push("금액 부족");  } else {    let left = m - p;    const used = [0, 0, 0, 0];    // 큰 동전부터: 자리 3(500원)에서 0(10원)으로 거꾸로    for (let i = 3; i >= 0; i--) {      used[i] = Math.min(Math.floor(left / COINS[i]), stock[i]);      left -= used[i] * COINS[i];    }    const ok = left === 0;    if (ok) {      for (let i = 0; i < 4; i++) stock[i] -= used[i];      out.push([used[3], used[2], used[1], used[0]].join(" "));    } else {      out.push("거스름돈 없음"); // 자판기 동전은 건드리지 않았다    }  }}console.log(out.join("\n"));
TypeScriptmain.ts · 28 줄
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const COINS: number[] = [10, 50, 100, 500];const stock: number[] = lines[0].trim().split(/\s+/).map(Number);const q: number = Number(lines[1]);const out: string[] = [];for (let t = 0; t < q; t++) {  const [p, m] = lines[2 + t].trim().split(/\s+/).map(Number);  if (m < p) {    out.push("금액 부족");  } else {    let left: number = m - p;    const used: number[] = [0, 0, 0, 0];    // 큰 동전부터: 자리 3(500원)에서 0(10원)으로 거꾸로    for (let i = 3; i >= 0; i--) {      used[i] = Math.min(Math.floor(left / COINS[i]), stock[i]);      left -= used[i] * COINS[i];    }    const ok: boolean = left === 0;    if (ok) {      for (let i = 0; i < 4; i++) stock[i] -= used[i];      out.push([used[3], used[2], used[1], used[0]].join(" "));    } else {      out.push("거스름돈 없음"); // 자판기 동전은 건드리지 않았다    }  }}console.log(out.join("\n"));
JavaMain.java · 36 줄
import java.util.Scanner; public class Main {    public static void main(String[] args) {        Scanner sc = new Scanner(System.in);        int[] coins = {10, 50, 100, 500};        int[] stock = new int[4];        for (int i = 0; i < 4; i++) stock[i] = sc.nextInt();        int q = sc.nextInt();        StringBuilder out = new StringBuilder();        for (int t = 0; t < q; t++) {            int p = sc.nextInt();            int m = sc.nextInt();            if (m < p) {                out.append("금액 부족\n");            } else {                int left = m - p;                int[] used = new int[4];                // 큰 동전부터: 자리 3(500원)에서 0(10원)으로 거꾸로                for (int i = 3; i >= 0; i--) {                    used[i] = Math.min(left / coins[i], stock[i]);                    left -= used[i] * coins[i];                }                boolean ok = left == 0;                if (ok) {                    for (int i = 0; i < 4; i++) stock[i] -= used[i];                    out.append(used[3]).append(' ').append(used[2]).append(' ')                       .append(used[1]).append(' ').append(used[0]).append('\n');                } else {                    out.append("거스름돈 없음\n"); // 자판기 동전은 건드리지 않았다                }            }        }        System.out.print(out);    }}
C#Main.cs · 42 줄
using System;using System.Linq; class Program{    static void Main()    {        int[] coins = { 10, 50, 100, 500 };        int[] stock = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToArray();        int q = int.Parse(Console.ReadLine());        for (int t = 0; t < q; t++)        {            int[] pm = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToArray();            int p = pm[0], m = pm[1];            if (m < p)            {                Console.WriteLine("금액 부족");            }            else            {                int left = m - p;                int[] used = new int[4];                // 큰 동전부터: 자리 3(500원)에서 0(10원)으로 거꾸로                for (int i = 3; i >= 0; i--)                {                    used[i] = Math.Min(left / coins[i], stock[i]);                    left -= used[i] * coins[i];                }                bool ok = left == 0;                if (ok)                {                    for (int i = 0; i < 4; i++) stock[i] -= used[i];                    Console.WriteLine($"{used[3]} {used[2]} {used[1]} {used[0]}");                }                else                {                    Console.WriteLine("거스름돈 없음"); // 자판기 동전은 건드리지 않았다                }            }        }    }}
C++main.cpp · 33 줄
#include <algorithm>#include <array>#include <iostream> int main() {    const std::array<int, 4> coins = {10, 50, 100, 500};    std::array<int, 4> stock;    for (int& s : stock) std::cin >> s;    int q;    std::cin >> q;    for (int t = 0; t < q; t++) {        int p, m;        std::cin >> p >> m;        if (m < p) {            std::cout << "금액 부족\n";        } else {            int left = m - p;            std::array<int, 4> used{};            // 큰 동전부터: 자리 3(500원)에서 0(10원)으로 거꾸로            for (int i = 3; i >= 0; i--) {                used[i] = std::min(left / coins[i], stock[i]);                left -= used[i] * coins[i];            }            bool ok = left == 0;            if (ok) {                for (int i = 0; i < 4; i++) stock[i] -= used[i];                std::cout << used[3] << ' ' << used[2] << ' ' << used[1] << ' ' << used[0] << '\n';            } else {                std::cout << "거스름돈 없음\n"; // 자판기 동전은 건드리지 않았다            }        }    }}
Cmain.c · 34 줄
#include <stdbool.h>#include <stdio.h> int main(void) {    const int coins[4] = {10, 50, 100, 500};    int stock[4];    for (int i = 0; i < 4; i++) scanf("%d", &stock[i]);    int q;    scanf("%d", &q);    for (int t = 0; t < q; t++) {        int p, m;        scanf("%d %d", &p, &m);        if (m < p) {            puts("금액 부족");        } else {            int left = m - p;            int used[4] = {0};            // 큰 동전부터: 자리 3(500원)에서 0(10원)으로 거꾸로            for (int i = 3; i >= 0; i--) {                int can = left / coins[i];                used[i] = can < stock[i] ? can : stock[i];                left -= used[i] * coins[i];            }            bool ok = left == 0;            if (ok) {                for (int i = 0; i < 4; i++) stock[i] -= used[i];                printf("%d %d %d %d\n", used[3], used[2], used[1], used[0]);            } else {                puts("거스름돈 없음"); // 자판기 동전은 건드리지 않았다            }        }    }    return 0;}
Craykonmain.cray · 37 줄
COINS = [10, 50, 100, 500];stock = 콘솔.수들읽기();q = 콘솔.줄읽기().수로변환();반복 (t = 0; t < q; t++){    pm = 콘솔.수들읽기();    p = pm[0];    m = pm[1];    만약 (m < p)    {        콘솔.쓰기("금액 부족");    }    아니면    {        left = m - p;        used = [0, 0, 0, 0];        // 큰 동전부터: 자리 3(500원)에서 0(10원)으로 거꾸로        반복 (i = 3; i >= 0; i--)        {            used[i] = 수학.작은수(수학.몫(left, COINS[i]), stock[i]);            left -= used[i] * COINS[i];        }        ok = left == 0;        만약 (ok)        {            반복 (i = 0; i < 4; i++)            {                stock[i] -= used[i];            }            콘솔.쓰기([used[3], used[2], used[1], used[0]]);        }        아니면        {            콘솔.쓰기("거스름돈 없음"); // 자판기 동전은 건드리지 않았다        }    }}