求解硬币问题。有1分、2分、5分、10分、50分和100分的硬币各若干枚,现在要用这些硬币支付W元,最少需要多少枚硬币?

1、我解决该问题编程的思路如下:
首先是利用一个数组A存储硬币面额,再利用另外一个数组B存储每个硬币面额对应的硬币数,利用贪心法的思想,当输入金额为W元时与最大面额的硬币作比较,若是大于面额最大的硬币则是可以取面额最大的硬币进行支付对应的数组B中的元素进行B[i]++,并且将其W-取出的硬币面额=剩下的钱,否则将其输入的W 与硬币面额次大的比较这时候也就是A数组下标后移一位(这里我是将硬币的面额进行了降序排列所以是后移一位,若是升序排列则是前移一位)判断二者大小,大的话执行B[i]++和w=w-A[i]操作,小的话执行i++操作(A数组小标后移一位),这样进行一个循环比较操作,并记录输入W元求出各硬币面额对应的个数,最后对B数组做一个求和操作,算出最少需要硬币数为多少。
2、根据题目要求实现该我问题的代码如下所示:


```java
package practical;
import java.util.Scanner;
public class Coins {public static int CoinSum(int w) {//求返回的硬币的个数int[] A={100,50,10,2,1};//一位数组存储面额int[] B={0,0,0,0,0};//用来存储数组A中对应面额的硬币个数int sum=0;if(w<1) {System.out.println("不存在这种情况输入不合法");}else{for(int i=0;i<5;) {if(A[i]<=w) {B[i]++;//对应面额的硬币个数进行+1操作w=w-A[i];//剩余钱的额度if(w==0)break;}else {//当A[i]>w的时候i++即取后一位进行比较i++;}}     }System.out.println("硬币面额:");for(int i=0;i<5;i++){System.out.printf(A[i]+" ");}System.out.println(" ");System.out.println("各硬币面额对应的硬币数量:");for(int j=0;j<5;j++){System.out.printf(B[j]+" ");}System.out.println(" ");for(int j=0;j<5;j++) {//对硬币个数进行求和操作sum=sum+B[j];}return sum;}public static void main(String[] args) {Scanner sc=new Scanner(System.in);System.out.println("输入需要支付的金额为:");int w=sc.nextInt();System.out.println("输出所需硬币的个数为:"+CoinSum(w));;sc.close();}
}

测试结果图如下所示:
测试截图一:

测试截图二:

3、将硬币的面额都化成元来进行计算,因为题目中是说支付W元所需要的最少的硬币数量,像上面的代码都是输入的整数值,实际生活中支付的金额有可能是包含小数的,代码如下所示(与上面代码相比只是做了些许修改,将其输入的int类型改为double类型的数据,而且值得注意的是double类型的数据做加减乘除会出现精度丢失问题如何解决代码中有注释)。
Java代码如下所示:

package practical;
import java.util.Scanner;
import java.math.*;
public class Coins1 {public static int CoinSum(double w) {//求返回的硬币的个数double[] A={1.0,0.5,0.1,0.02,0.01};//一位数组存储面额int[] B={0,0,0,0,0};//用来存储数组A中对应面额的硬币个数int sum=0;if(w<0.01) {System.out.println("不存在这种情况输入不合法");}else{for(int i=0;i<5;) {if(A[i]<=w) {B[i]++;//对应面额的硬币个数进行+1操作BigDecimal p1 = new BigDecimal(Double.toString(w));//先是将double类型转换成String类型//让后将其转换成BigDecimal类型进行计算,不然在计算的时候浮点数类型会出现精度丢失,导致运算结果有偏差BigDecimal p2 = new BigDecimal(Double.toString(A[i]));w=p1.subtract(p2).doubleValue();//剩余钱的额度}else {//当A[i]>w的时候i++即取后一位进行比较i++;}}      }System.out.println("硬币面额:");for(int i=0;i<5;i++){System.out.printf(A[i]+" ");}System.out.println(" ");System.out.println("各硬币面额对应的硬币数量:");for(int j=0;j<5;j++){System.out.printf(B[j]+" ");}System.out.println(" ");for(int j=0;j<5;j++) {//对硬币个数进行求和操作sum=sum+B[j];}return sum;}public static void main(String[] args) {Scanner sc=new Scanner(System.in);System.out.println("输入需要支付的金额为:");double w=sc.nextDouble();System.out.println("输出所需硬币的个数为:"+CoinSum(w));;sc.close();}
}

测试截图如下所示:
测试截图一:

测试截图二:

上面这个程序值得注意的是,浮点类型数进行加减乘除操作的时候,会出现精度丢失的现象。为什么会出现这种现象的原因:主要是由于计算机中二进制无法精确的表示浮点数类型数据。在计算机中做加减乘除,最后都会将其转化成二进制进行加减乘除运算所以就会导致精度缺失问题。
所以这个时候就应该利用到java.math.中提供的一个API类,BigDecimal。
float和double只能用来做科学计算或者是工程计算,在商业计算中要用java.math.BigDecimal。BigDecimal所创建的是对象,我们不能使用传统的+、-、
、/等算术运算符直接对其对象进行数学运算,而必须调用其相对应的方法。方法中的参数也必须是BigDecimal的对象。构造器是类的特殊方法,专门用来创建对象,特别是带有参数的对象
BigDecimal一共有4个构造方法:
BigDecimal(int) 创建一个具有参数所指定整数值的对象。
BigDecimal(double) 创建一个具有参数所指定双精度值的对象。(不建议采用,这个仍旧出现精度丢失错误)
BigDecimal(long) 创建一个具有参数所指定长整数值的对象。
BigDecimal(String) 创建一个具有参数所指定以字符串表示的数值的对象(用的较多)
像上面第二个程序中输入一个double类型的数据进行减法运算,最后出现精度丢失的错误,我开始是利用BigDecimal(double)来避免精度丢失,但是没有成功,仍旧是精度处于丢失状态,所以这时候就利用BigDecimal(String),首先是将double类型转换成String类型Double.toString(A[i]),然后就将其转换成BigDecimal类型,最后将运算的结果再装换成double类型,即p1.substract(p2).doubleValue();
转换成BigDecimal后做加减乘除形式:
p1.add(p2);//加法
p1.substract(p2);//减法
p1.mutiply(p2);//乘法
p1.divide(p2);//除法

Java实现求解硬币问题有1分、2分、5分、10分、50分和100分的硬币各若干枚,现在要用这些硬币支付W元,最少需要多少枚硬币?利用贪心法的思想进行编程相关推荐

  1. 贪心法求解硬币问题和乘船问题

    贪心算法基本要素: 贪心选择性质:问题的最优解可以通过贪心选择实现(也就是先实现局部最优解,然后整体最优解可以通过一系列局部最优的选择来达到) 最优子结构性质:问题的最优解包含子问题的最优解 贪心算法 ...

  2. 【挑战程序设计竞赛】- 2.2贪心法(硬币最少、区间覆盖、字典序最小、标记最少、木板切割)

    四年前犯的错再做一遍还是会犯. 四年前不看presentation要求,四年后依然PE. 四年前忘记longlong,四年后还是会忘. 2.2 贪心法 核心思想:不断选取最优策略. 例题1-硬币:有1 ...

  3. TSP问题解决:模拟退火、贪心法、爬山法,Python实现

    TSP问题解决:模拟退火.贪心法.爬山法,Python实现这里写目录标题 一.TSP问题 二.简单介绍:贪心法.爬山法.模拟退火 三.python代码实现 四.分别用这三种方法得出结果,进行比较 一. ...

  4. 基于python程序利用贪心算法解决旅行家的预算问题

    程序已通过检测:  https://www.dotcpp.com/oj/problem1640.html 问题描述 一个旅行家想驾驶汽车以最少的费用从一个城市到另一个城市(假设出发时油箱是空的).给定 ...

  5. 福师2018计算机应用基础,中石油华东《计算机应用基础》2018年秋学期在线作业100分答案满分...

    <计算机应用基础>2018年秋学期在线作业(一) 共题,总分:100分 时间:30分0秒 答题中 分一.单选题共20题,100分 15分 在Windows中,"写字板" ...

  6. CCF201709-1 打酱油(100分)【水题】

    试题编号: 201709-1 试题名称: 打酱油 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 小明带着N元钱去买酱油.酱油10块钱一瓶,商家进行促销,每买3瓶送1瓶,或者每 ...

  7. CCF201512-1 数位之和(100分)【进制+文本】

    试题编号: 201512-1 试题名称: 数位之和 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 给定一个十进制整数n,输出n的各位数字之和. 输入格式 输入一个整数n. 输 ...

  8. CCF201509-1 数列分段(100分)【序列处理】

    试题编号: 201509-1 试题名称: 数列分段 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 给定一个整数数列,数列中连续相同的最长整数序列算成一段,问数列中共有多少段? ...

  9. CCF201403-4 无线网络(100分)

    试题编号: 201403-4 试题名称: 无线网络 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 目前在一个很大的平面房间里有 n 个无线路由器,每个无线路由器都固定在某个点 ...

最新文章

  1. oracle dba 手动创建数据实例
  2. 【读书笔记】《编写高效的JavaScript程序》
  3. NewCode----给定两个数R和n,输出R的n次方
  4. 没有什么多模态任务是一层Transformer解决不了的!
  5. 关于事件委托的整理 ,另附bind,live,delegate,on区别
  6. UVA 1152 4 Values Whose Sum is Zero 和为0的4个值 (中途相遇)
  7. Lucene 和 ElasticSearch 的前世今生
  8. ef多条件映射_Hibernate一对一关系映射
  9. java操作Excel实现读写
  10. [ZJOI2008]生日聚会
  11. 汉王手写板linux驱动下载,Hanwang汉王
  12. 南京大学计算机学硕博士,2019年南京大学计算机软件研究所招收研究生说明
  13. Scrapy爬虫入门教程十 Feed exports(导出文件)
  14. 生物特征识别六大技术,你知道多少?
  15. 程序员要为了生活而工作,不要为了工作而生活。
  16. 9.29 正睿提高6
  17. 安卓Bmob后端云的使用(增删改查、上传图片、推送服务等)
  18. 基于S3C2410A的MDB/ICP协议的实现
  19. TextView简介
  20. 原创|为什么说要功利性学习?

热门文章

  1. mysql查看具体表_MySQL查看表的详细信息
  2. 黑马程序员|C++教程(56 指针-指针的定义和使用_)
  3. wsl2显示无NVIDIA显卡驱动
  4. 心情随笔--Dream1
  5. python顺序执行多个脚本_一个脚本调用多个脚本依次执行
  6. 【技术简史】1995-1996 开启的互联网时代范式:信息无处不在
  7. 代码执行与命令执行的区别
  8. 计算机接口查询,免费的国家违章车辆查询API接口及其使用方法
  9. 对接极兔速递物流开放平台API接口指南-快递鸟
  10. 第十一届蓝桥杯嵌入式设计与开发 (省赛)