{ }codelper
倒序循环嵌套条件布尔值P0127

自动售货机找零

自动售货机给顾客找零。
硬币有 10 韩元、50 韩元、100 韩元、500 韩元四种。
第一行按此顺序给出售货机里 10、50、100、500 韩元硬币的个数。
第二行给出顾客人数 q,接下来 q 行给出每位顾客的商品价格 p 和投入的钱 m。
顾客投入的钱另外收集,不用来找零。
按顺序处理顾客,每位顾客输出一行。
如果 m 小于 p,输出 "金额不足"。
否则按 500、100、50、10 韩元的顺序凑出找零 c = m - p。
每种硬币在不超过剩余金额、也不超过售货机剩余个数的前提下尽量多用。
如果这样恰好凑出 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()/标准输入传入(运行中不会等待输入)。

$ 就绪

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

其他语言怎么写?查看各语言题解 · 8 种语言题解

输入从小硬币开始,计算和输出却从大硬币开始。
所以要从后往前遍历数组:Python range(3, -1, -1)(终点 -1 不包含,所以走到 0),C 系、JS、TS for (i = 3; i >= 0; i--),Craykon 循环 (i = 3; i >= 0; i--)。
从小硬币开始会得到找出一大堆 10 韩元的错误答案。
要用的个数是 min(剩余金额 / 面值, 剩余个数)。
整数商在 Python 是 //,JS/TS Math.floor(a / b),Craykon 数学.商(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,Craykon 真/假。
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]]);        }        否则        {            控制台.输出("无法找零"); // 자판기 동전은 건드리지 않았다        }    }}