function checkCashRegister(price, cash, cid) {
var change;
var sumCid = 0; // Here is your change, ma'am. //找零(change),付款(cash),购买价格(price),收银机中零钱(cid)
change = cash - price; //计算零钱总额
for (var i = 0; i < cid.length; i++) {
sumCid += cid[i][1];
}
return sumCid;
sumCid = Number(sumCid.toFixed(2)); //保留两位小数 if (sumCid < change) {
return "Insufficient Funds"; //余额不足
} else if (sumCid === change) {
return "Closed";
} else {
// 1.零钱不够,返回余额不足
// 2.零钱足够,找回零钱
return overChange(change, cid, sumCid);
}
} function overChange(change, arr, sumCid) {
var array = [];
var len = arr.length; for (var i = len - 1; i >= 0; i--) {
if (arr[i][1] === 0) continue; if (arr[i][1] < change) {
array.push(arr[i]);
change -= arr[i][1];
change = Number(change.toFixed(2));
} else if (arr[i][1] > change) {
var x = arr[i][0]; // 取得零钱名称
var y = 0; switch(x) {
case "ONE HUNDRED":
y = Math.floor(change / 100) * 100;
break;
case "TWENTY":
y = Math.floor(change / 20) * 20;
break;
case "TEN":
y = Math.floor(change / 10) * 10;
break;
case "FIVE":
y = Math.floor(change / 5) * 5;
break;
case "ONE":
y = Math.floor(change / 1);
break;
case "QUARTER":
y = Math.floor(change / 0.25) * 0.25;
break;
case "DIME":
y = Math.floor(change / 0.10) * 0.10;
break;
case "NICKEL":
y = Math.floor(change / 0.05) * 0.05;
break;
case "PENNY":
y = Math.floor(change / 0.01) * 0.01;
break;
} if (y === 0 && sumCid - arr[i][1] < change) {
  return "Insufficient Funds";
} else if (y === 0) {
continue;
} else {
if (y < 1) {
y = y;
}
var array1 = [];
array1.push(arr[i][0]);
array1.push(y);
array.push(array1);
change -= y;
change = Number(change.toFixed(2));
}
}
} if (change === 0) {
return array;
} else {
return "Insufficient Funds";
} }

题目:

  设计一个收银程序 checkCashRegister() ,其把购买价格(price)作为第一个参数 , 付款金额 (cash)作为第二个参数, 和收银机中零钱 (cid) 作为第三个参数.

cid 是一个二维数组,存着当前可用的找零.

当收银机中的钱不够找零时返回字符串 "Insufficient Funds". 如果正好则返回字符串 "Closed".

否则, 返回应找回的零钱列表,且由大到小存在二维数组中.

分析:

  一个模拟找钱的程序。思路应该是这样的:

  首先,分析函数的参数,第一个参数是商品价格price,第二参数是支付现金金额cash,第三个是柜员机当前的零钱cid,是一个二维数组,它已经将所拥有的相同面值的钱币做了一个累加,比如面值为5元的就剩35元了这样。

  然后我们来分析函数的实现逻辑,结账时,会先扫描一下商品的价格,做一个累加,得到总的支付金额比如说78元,然后你给的钱是现金的话是不是要给50+20+5+1*3或者10*7+1*8等等等的组合。

  //找零(change),付款(cash),购买价格(price),收银机中零钱(cid)
change = cash - price;

但是你刚好没有零钱,最小100,你只能给100。那么此时基于交易等价交换的原则,柜员机得找零对吧,而且得找得回这么多零钱对吧,找不回就返回字符串"Insufficient Funds",表示零钱不足,交易基于等价交换的原则无法进行。那么你要先求找零的金额大小,然后与柜员机当前的零钱总额作比较。找零的金额为 cash - price,当前柜员机的零钱总额为各个面值大小的纸币的金额总额相加。数组是规律的,第一项是钱币面值,第二项是该面值的钱币总额。所以可以循环遍历叠加金额。

//计算零钱总额
for (var i = 0; i < cid.length; i++) {
sumCid += cid[i][1];
}

当可以找零的时候,你会拿钱,而且是一个面值的纸币一个面值的纸币的拿吧,不会找27元你找个27个一元钱吧。最简便的做法总是先给一张较大的但小于当前需要找零的零钱的纸币。这是使用循环变量递减的原因。

 for (var i = len - 1; i >= 0; i--) {

你没找零多少钱需要找得零钱总额在减小

change -= y;

还有一种情况就是,有可能柜员机零钱总额足够找零,但是找不开,比如说要找零3元,但你最小的纸币只剩下5元了,这时也是需要返回字符串"Insufficient Funds",表示零钱不足,交易基于等价交换的原则无法进行。

  if (y === 0 && sumCid - arr[i][1] < change) {
return "Insufficient Funds";
}
if (change === 0) {
return array;
} else {
return "Insufficient Funds";
}

change == 0 是判断能否成功找零的直接标准。

如果循环结束了,change != 0,说明现在的零钱找不开。否则返回需要找回的零钱。

方法参考文档

  

  Number.prototype.toFixed()

    toFixed() 方法使用定点表示法来格式化一个数。

    https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed

  

Exact Change FreeCodeCamp的更多相关文章

  1. Exact Change(背包HDU2753)

    Exact Change Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...

  2. FCC高级编程篇之Exact Change

    Exact Change Design a cash register drawer function checkCashRegister() that accepts purchase price ...

  3. Exact Change(01背包)

    描述 Seller: That will be fourteen dollars. Buyer: Here's a twenty. Seller: Sorry, I don't have any ch ...

  4. Exact Change

    设计一个收银程序 checkCashRegister() ,其把购买价格(price)作为第一个参数 , 付款金额 (cash)作为第二个参数, 和收银机中零钱 (cid) 作为第三个参数. cid ...

  5. [Advanced Algorithm] - Exact Change

    题目 设计一个收银程序 checkCashRegister(),其把购买价格(price)作为第一个参数 , 付款金额 (cash)作为第二个参数, 和收银机中零钱 (cid) 作为第三个参数. ci ...

  6. UVA-11517 Exact Change(DP)

    题目大意:有n张钞票,面值可能不同.你要买一件东西,可能需要找零钱.问最少付多少钱,并求出最少的钞票张数. 题目分析:定义状态dp(i,w)表示前i张钞票凑成w元需要的最少钞票张数.则状态转移方程为d ...

  7. FCC(ES6写法) Exact Change

    设计一个收银程序 checkCashRegister() ,其把购买价格(price)作为第一个参数 , 付款金额 (cash)作为第二个参数, 和收银机中零钱 (cid) 作为第三个参数. cid  ...

  8. FreeCodeCamp 高级算法(个人向)

    freecodecamp 高级算法地址戳这里. freecodecamp的初级和中级算法,基本给个思路就能完成,而高级算法稍微麻烦了一点,所以我会把自己的解答思路写清楚,如果有错误或者更好的解法,欢迎 ...

  9. Codeforces Round #598 (Div. 3) A. Payment Without Change 水题

    A. Payment Without Change You have a coins of value n and b coins of value 1. You always pay in exac ...

随机推荐

  1. 爬虫系列(八) 用requests实现天气查询

    这篇文章我们将使用 requests 调用天气查询接口,实现一个天气查询的小模块,下面先贴上最终的效果图 1.接口分析 虽然现在网络上有很多免费的天气查询接口,但是有很多网站都是需要注册登陆的,过程比 ...

  2. Spring Cloud系列(二) 介绍

    Spring Cloud系列(一) 介绍 Spring Cloud是基于Spring Boot实现的微服务架构开发工具.它为微服务架构中涉及的配置管理.服务治理.断路器.智能路由.微代理.控制总线.全 ...

  3. MongoDB简介、特点、原理、使用场景、应用案例

    简介 MongoDB[1] 是一个基于分布式文件存储的数据库.由C 语言编写.旨在为WEB应用提供可扩展的高性能数据存储解决方案. MongoDB[2] 是一个介于关系数据库和非关系数据库之间的产品, ...

  4. 【hihocoder 1476】矩形计数

    [题目链接]:http://hihocoder.com/problemset/problem/1476 [题意] [题解] 首先不考虑黑格子,计算出一共有多少个矩形: 枚举矩形的大小r×c,这样大小的 ...

  5. hdu 4857 逆向拓扑排序+反向输出

    /*一组测试实例 4 4 2 3 1 2 4 */ #include<stdio.h> #include<string.h> #include<queue> usi ...

  6. fzoj 2113数位dp

    参考http://blog.csdn.net/xingyeyongheng/article/details/8785785 #include<stdio.h> #define ll lon ...

  7. innodb_support_xa=1

    mysql> show create table t; CREATE TABLE `t` ( `id` ) NOT NULL AUTO_INCREMENT, `num` ) DEFAULT NU ...

  8. 能够替代浮动的inline-block

    浮动有个缺点:脱离了原来的文档流,导致父容器无高度.使用inline-block不会脱离文档流.且无忘记清空浮动的困扰 并排的div都设置position:inline-block,vertical- ...

  9. IJKPlayer问题集锦之不定时更新

    1.IJKPlayer 不像系统播放器会给你旋转视频角度,所以你需要通过onInfo的what == IMediaPlayer.MEDIA_INFO_VIDEO_ROTATION_CHANGED去获取 ...

  10. vim设置为indent折叠以后,每次打开文件时代码处于折叠状态,能改变吗?

    vim设置为indent折叠以后,每次打开文件时代码处于折叠状态.即使这次编辑的时候把折叠展开,保存关闭文件,重新打开,所有的代码都又折叠起来了. 请问有没有默认不折叠的方法? 是否有可以一次展开所有 ...