AcWing 656. 钞票和硬币(非放大法,两个for循环解决问题)
原题链接
中等
作者:
九里今天学点什么呢
,
2021-04-17 23:55:58
,
所有人可见
,
阅读 5625
#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
int main(){
double n;
cin>>n;
//钞票面额数组
double nota[6]={100,50,20,10,5,2};
//硬币面额数组
double modea[6]={1,0.5,0.25,0.1,0.05,0.01};
//钞票输出
cout<<"NOTAS:"<<endl;
for(int i=0;i<6;i++){
//num为当前面额为nota[i]的钞票所需张数
int num=int(n/nota[i]);
printf("%d nota(s) de R$ %.2lf\n",num,nota[i]);
n=n-num*nota[i];
}
//硬币输出
cout<<"MOEDAS:"<<endl;
for(int i=0;i<6;i++){
//num为当前面额为modea[i]的硬币所需个数,面额最小为10e-2
int num=int(n/modea[i]+10e-3);//通过加一个10e-3来防止精度问题
printf("%d moeda(s) de R$ %.2lf\n",num,modea[i]);
n=n-num*modea[i];
}
return 0;
}
我是新手,为啥加了0.0001就能防止精度问题啊
同问
浮点误差
是的,int 再设钱数变量更简单
感觉加0.0001有点取巧的意味了,还是乘以100变为int类型好一点。
有没有大佬看看怎么修改
# include[HTML_REMOVED]
# include[HTML_REMOVED]
using namespace std;
int main()
{
double n;
cin >>n;
}
#include[HTML_REMOVED]
#include[HTML_REMOVED]
#include[HTML_REMOVED]
using namespace std;
const long long Maxn=0x3ffffff,Minm=-0x3ffffff;
int c[111],i=0,d[111];
int main()
{
double x,a[7]={100,50,20,10,5,2,1},b[7]={0.50,0.25,0.10,0.05,0.01};
scanf(“%lf”,&x);
double y=x-(int)x,z=(int)x;
for(int i=0;i<7&&z!=0;i)
{
c[i]=z/a[i];
z=z-c[i]*a[i];
}
for(int i=0;i<5&&y!=0;i)
{
} 能不能帮我看看,为谁出现466.01,566,.02之类的单独带分的出来的结果有问题
moe
感谢帮忙解决了这个问题,但对于精度问题还是比较疑惑。
第一个for循环是否改变了第二个for循环中n的取值啊
同问,为什么加0.0001可以防止精度问题
如果你输入的是156.03,在变量里储存的不是156.03而是153.02999999,所以要加0.0001
应该是156.0300000000000001234412这样的吧,如果是double, 怎么会是156.02999999999
可能是编译器的问题
那加0.0001不就是156.030100000000000001234412了么?为什么这个时候就好了?
我也不知道说的对不对啊,精度问题是由于小数部分转化为二进制过程中产生的问题。假如输入156.03,变量储存会变成153.02999999,在加上0.0001后再保留2位小数,其后的部分便被舍去了。对于结果而言防止了精度问题。但是实际上无法彻底解决问题。
第一个for循环是否改变了第二个for循环中n的取值啊
肯定变了啊
0.3 可能在存储时变成 0.29999999999999993 或者 0.30000000000000000。 +一个很小的数 会精确
这个好清楚 :D
谢谢~~