题目描述
描述
今天TheBeet去门口那家山东煎饼小摊买煎饼,到他付钱的时候他才发现,他的钱包里面只有一张100块。于是他需要把这张100块钱破开,但是TheBeet不喜欢硬币,另外由于某种原因,TheBeet也不喜欢20元的纸币,另外也不喜欢钱包里面有太多张纸币,所以他希望拿到尽量少的纸币数。给出摊主现有的纸币数量,求摊主要如何找零给TheBeet才能满足他的要求。
输入
输入的第一行是一个正整数N(1 <= N <= 40),表示TheBeet买了N个山东煎饼,已知每个山东煎饼价格为2.5元。接下来有6个非负整数,范围在[0, 1000]之内,分别表示摊主所拥有的50元、10元、5元、1元、5角、1角纸币的数量。
输出
输出一个整数,表示TheBeet最后收到的纸币数。如果无法满足要求,那就输出-1。
输入样例 1
2
100 100 100 100 100 100
输出样例 1
6
题目分析
本题是一道贪心算法题,只要每次都用 目前能使用的 最大面额纸币找钱即可解决问题。唯一值得聚焦的是本题在C的编译环境里会出现舍入误差,也就是说,最后老板找完剩下的钱在本题内并不是0,而是一个很小的值。这可能导致最后的条件判断问题。解决办法有两种,一种是扩大数据,比如把要找的100块钱、煎饼价格、所有的钱的面额都乘以10. 另一种是改变判断条件,最后判断是否能成功找完要找的钱时,把
if(剩下的钱 == 0)
改成
if(剩下的钱 < 0.01 且 n > -0.01)
(当然,在核心代码中的与剩下钱数有关的部分也要进行类似处理)
以下为完整代码
#include <iostream>
using namespace std;
float money[6]={50,10,5,1,0.5,0.1};
int main()
{
float n;
int pieces = 0;
cin>>n;
if(n < 1 || n > 40){
cout<<-1;
return 0;
}
int num[6];
for(int i = 0 ; i < 6 ; i ++){
cin>>num[i];
if(num[i] < 0 || num[i] > 1000){
cout<<-1;
return 0;
}
}
float remain = 100-n*2.5;
for(int j = 0 ; j < 6 ; j ++){
while(remain+0.0001 >= money[j] && num[j] > 0){
// cout<<"remain: "<<remain<<"\n";
remain -= money[j];
num[j]--;
pieces++;
}
}
if(remain < 0.01 && n > -0.01){
cout<<pieces;
}
else{
cout<<-1;
}
return 0;
}