做题思路
注意:每一种钱的张数都是若干张,都没有明确的指明,但是通过组合成为3.5我们易得出每一种钱的最大张数。
种类 | 最大张数 |
1角 | 35 |
2角 | 17 |
5角 | 7 |
1元 | 3 |
正确做法一
所以利用循环语句以及条件语句,可以得到以下代码:
#include <stdio.h>
int main()
{
int i1 = 0;int i2 = 0;
int i5 = 0;int i10 = 0;
int count = 0;
for (i1 = 0; i1 <= 35; i1++)
{
for (i2 = 0; i2 <= 17; i2++)
{
for (i5 = 0; i5 <= 7; i5++)
{
for (i10 = 0; i10 <= 3; i10++)
{
if (i1 * 1 + i2 * 2 + i5 * 5 + i10 * 10 == 35)
{
count++;
printf("第%d种情况:1角:%d;2角:%d;5角:%d;1元:%d\n",
count,i1, i2, i5, i10);
}
}
}
}
}
printf("一共%d种情况\n", count);
return 0;
}
此时运行结果正确为:140种情况。
上面的代码为了方便,我们将其角、元的单位都化为一致。那么如果我们不划分呢?
#include <stdio.h>
int main()
{
int i1 = 0;int i2 = 0;
int i5 = 0;int i10 = 0;
int count = 0;
for (i1 = 0; i1 <= 35; i1++)
{
for (i2 = 0; i2 <= 17; i2++)
{
for (i5 = 0; i5 <= 7; i5++)
{
for (i10 = 0; i10 <= 3; i10++)
{
if (i1 * 0.1 + i2 * 0.2 + i5 * 0.5 + i10 * 1 == 3.5)
{
count++;
printf("第%d种情况:1角:%d;2角:%d;5角:%d;1元:%d\n",
count, i1, i2, i5, i10);
}
}
}
}
}
printf("一共%d种情况\n", count);
return 0;
}
此时,运行的结果竟然是:一共126种情况。为什么会不一样呢?
面试点:正确地表示浮点型val与0相等
这里便是面试点了!正确的表示浮点型val与0相等?
其实这里0.1是double类型的数,它不仅仅是0.1而是0.1000000000000000004,而0.2、0.5也是如此。这些都是有精度差的。在通常情况下,只要精度范围在-0.000001~0.000001之内就算作正确,所以就是val<=0.000001并且-0.000001<=val就认为val=0。
又因为在C语言中规定,abs(x)表示为整形x的绝对值;fabs(x)表示为浮点形x的绝对值
正确的表示浮点型val与0相等:
abs(val - 0)< = 0.000001
所以要正确表达:组合数之和为3.5,应该如下:
fabs((i1 * 0.1 + i2 * 0.2 + i5 * 0.5 + i10 * 1) - 3.5) < 0.000001
在这里,我们需要定义新的精度为0.000001,并且包含头文件:math.h
#define EPS 0.000001
#include <math.h>
正确做法二
所以正确的做法:
#include <stdio.h>
#include <math.h>
#define EPS 0.000001
int main()
{
int i1 = 0;int i2 = 0;
int i5 = 0;int i10 = 0;
int count = 0;
for (i1 = 0; i1 <= 35; i1++)
{
for (i2 = 0; i2 <= 17; i2++)
{
for (i5 = 0; i5 <= 7; i5++)
{
for (i10 = 0; i10 <= 3; i10++)
{
if (fabs((i1 * 0.1 + i2 * 0.2 + i5 * 0.5 + i10 * 1) - 3.5) < 0.000001)
{
count++;
printf("第%d种情况:1角:%d;2角:%d;5角:%d;1元:%d\n",
count, i1, i2, i5, i10);
}
}
}
}
}
printf("一共%d种情况\n", count);
return 0;
}