一.问题描述
设有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");
}
}