硬币找钱问题(Java)

一.问题描述

设有6种不同面值的硬币,各硬币的面值分别为5分、1角、2角、5角、1元和2元。现在要用这些面值的硬币来购物和找钱。购物时可以使用的各种面值的硬币个数存于数组Coins[1:6]中,假设商店里各面值的硬币有足够多。对于给定的付款金额,计算使用硬币个数最少的交易方案。输入数据的每一行有6个整数和一个有2位小数的实数,分别表示可以使用的各种面值的硬币个数和付款金额。输出为交易所需要的最少硬币个数,如果不可能完成交易,则输出“impossible”。

输入数据示例

2 4 2 2 1 0     0.95

2 4 2 0 1 0     0.55

输出示例

4

4

二、算法设计

注意事项:

        问题:double类型会出现精确度问题

解决办法:将1元==>100分    5角==>50分

1、数据初始化

需要用到一下数据:

double[][] coins = new double[6][2];       //5分、1角、2角、5角、1元、2元
        int pays = 0;                        //付款金额
        int sums=0;                         //需要的总个数
        int num=0;                          //每次的个数
        //初始化面额
        coins[0][0]= 0.05;
        coins[1][0]= 0.1;
        coins[2][0]= 0.2;
        coins[3][0]= 0.5;
        coins[4][0]= 1;
        coins[5][0]= 2;

2、输入数据

Scanner scan = new Scanner(System.in);
        System.out.println("请输入面值为5分、1角、2角、5角、1元和2元面值的硬币个数:");
        for (int i = 0; i < coins.length; i++) {
            System.out.println("请输入第"+(i+1)+"个硬币个数:");
            coins[i][1] = scan.nextInt();          //输入硬币数量
        }
        System.out.println("请输入付款金额(分为单位):");
        pays=scan.nextInt();                    //输入付款金额

3、排除部分

  //分位置:不是0或者5则无法找钱成功
        if (pays%10!=0&& pays%10!=5)  System.out.println("impossible");
        //分位置:5  但是没有5分的面额
        if (pays%10==5&&coins[0][0]==0)  System.out.println("impossible");

4、贪心算法

//贪心算法
        for(int i = coins.length-1; i >=0 ; i--) {  //从最大的面额开始遍历
            int money = (int) (coins[i][0]*100);         //面额大小   元==》分
             int existNum= (int) coins[i][1];    //硬币个数
            num= (int) (pays/money);
            if (num>coins[i][1]) num = existNum;   //超出个数,则num=existNum
            /**
             * 精确度有问题(转换成整数)
             */
            pays=pays-money*num;                   //剩余的总金额
            sums=sums+num;                         //累计硬币数
        }
        if (pays==0)System.out.println("总共需要硬币数:"+sums);    //输出总金额
        if (pays!=0) System.out.println("impossible");          //无法找零

三、总代码

import java.util.Scanner;

public class Solution {
    public static void main(String[] args) {
        /**
         * 硬币找钱问题
         */
        //初始化数据
        double[][] coins = new double[6][2];       //5分、1角、2角、5角、1元、2元=200分
        int pays = 0;                        //付款金额
        int sums=0;                         //需要的总个数
        int num=0;                          //每次的个数
        //初始化面额
        coins[0][0]= 0.05;
        coins[1][0]= 0.1;
        coins[2][0]= 0.2;
        coins[3][0]= 0.5;
        coins[4][0]= 1;
        coins[5][0]= 2;
        Scanner scan = new Scanner(System.in);
        System.out.println("请输入面值为5分、1角、2角、5角、1元和2元面值的硬币个数:");
        for (int i = 0; i < coins.length; i++) {
            System.out.println("请输入第"+(i+1)+"个硬币个数:");
            coins[i][1] = scan.nextInt();          //输入硬币数量
        }
        System.out.println("请输入付款金额(分为单位):");
        pays=scan.nextInt();                    //输入付款金额
        //分位置:不是0或者5则无法找钱成功
        if (pays%10!=0&& pays%10!=5)  System.out.println("impossible");
        //分位置:5  但是没有5分的面额
        if (pays%10==5&&coins[0][0]==0)  System.out.println("impossible");
        //贪心算法
        for(int i = coins.length-1; i >=0 ; i--) {  //从最大的面额开始遍历
            int money = (int) (coins[i][0]*100);         //面额大小   元==》分
             int existNum= (int) coins[i][1];    //硬币个数
            num= (int) (pays/money);
            if (num>coins[i][1]) num = existNum;   //超出个数,则num=existNum
            /**
             * 精确度有问题(转换成整数)
             */
            pays=pays-money*num;                   //剩余的总金额
            sums=sums+num;                         //累计硬币数
        }
        if (pays==0)System.out.println("总共需要硬币数:"+sums);    //输出总金额
        if (pays!=0) System.out.println("impossible");
    }
}

四、程序调试及运行结果分析

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小海豚_qy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值