鱼C论坛

 找回密码
 立即注册
查看: 2070|回复: 6

[已解决]某人想将手中的一张面值100元的人民币换成10元、5元、2元和1元面值的票子。要求换...

[复制链接]
发表于 2023-7-6 09:42:04 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
可以看懂用for的代码,但是当时做题我用了while循环,显示是死循环,但是不知道错在哪里,麻烦大佬们帮我看看这道题如何用while循环谢谢!
int main()
{
        int a=1, b=1, c=1, d=1;
        int n=0;
        while (0<a<40)
        {
                a++;
                while (0 < b < 40)
                {
                        b++;
                        while (0 < c < 40)
                        {
                                c++;
                                while (0 < d < 40)
                                {
                                        d++;
                                        if (a + b + c + d == 40 && a * 10 + b * 5 + c * 2 + d * 1 == 100)
                                        {
                                                n++;
                                        }
                                }
                        }
                }
               
        }
        printf("%d\n",n);
        return 0;
}
最佳答案
2023-7-6 09:45:26
你的代码确实存在一个死循环的问题,问题出在你的while循环条件中。在你的代码中,你设定了条件"0<a<40",在C语言中,这样的条件是无效的。这是因为在C语言中,比较运算符是两两进行的,不能进行这样的链式比较。你应该将这个条件分开写,即"a > 0 && a < 40"。然而,在这种情况下,由于你的a,b,c,d初始值都为1,且在每个while循环的开始都会自增,所以这个判断条件总是成立的,这就造成了死循环。

另外,在这个问题中,我们需要找出所有面值10元、5元、2元和1元的组合,使得总值等于100元,这意味着a,b,c,d可能的取值范围应该是0到100,而不是1到40。

修复这个问题后的代码可能如下所示:

  1. #include<stdio.h>

  2. int main() {
  3.     int a=0, b=0, c=0, d=0;
  4.     int n=0;
  5.     while (a <= 100)
  6.     {
  7.         b = 0;
  8.         while (b <= 100)
  9.         {
  10.             c = 0;
  11.             while (c <= 100)
  12.             {
  13.                 d = 0;
  14.                 while (d <= 100)
  15.                 {
  16.                     if (a * 10 + b * 5 + c * 2 + d * 1 == 100)
  17.                     {
  18.                         n++;
  19.                     }
  20.                     d++;
  21.                 }
  22.                 c++;
  23.             }
  24.             b++;
  25.         }
  26.         a++;
  27.     }
  28.     printf("%d\n",n);
  29.     return 0;
  30. }
复制代码


这个代码的运行时间可能会比较长,因为我们需要检查每一个可能的组合,这样的复杂度是O(n^4)。你可以通过一些优化来降低运行时间,例如,我们知道10元、5元、2元和1元的最大数量分别为10, 20, 50, 100,可以根据这个信息来限制循环的范围,从而减少运行时间。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-7-6 09:42:19 | 显示全部楼层
您使用的while循环存在一些问题,导致了死循环。问题在于您没有正确的更新循环条件的值,从而导致循环无法结束。以下是修正后的代码:
  1. c
  2. #include <stdio.h>
  3. int main() {
  4.     int a = 1, b = 1, c = 1, d = 1;
  5.     int n = 0;
  6.     while (a <= 40) {
  7.         b = 1;
  8.         while (b <= 40) {
  9.             c = 1;
  10.             while (c <= 40) {
  11.                 d = 1;
  12.                 while (d <= 40) {
  13.                     if (a + b + c + d == 40 && a [i] 10 + b [/i] 5 + c [i] 2 + d [/i] 1 == 100) {
  14.                         n++;
  15.                     }
  16.                     d++;
  17.                 }
  18.                 c++;
  19.             }
  20.             b++;
  21.         }
  22.         a++;
  23.     }
  24.     printf("%d\n", n);
  25.     return 0;
  26. }
复制代码

在修正后的代码中,每个内层循环都在开始时将循环变量重置为初始值。同时,我们在每个循环结束后递增循环变量的值,确保循环能够逐渐向终止条件靠近。这样就可以正确地计算出符合要求的换钱方式的数量了。

希望这可以解决您的问题!如果还有其他疑问,请随时向我提问。

点评

谢谢!  发表于 2023-7-6 10:02
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-7-6 09:45:26 | 显示全部楼层    本楼为最佳答案   
你的代码确实存在一个死循环的问题,问题出在你的while循环条件中。在你的代码中,你设定了条件"0<a<40",在C语言中,这样的条件是无效的。这是因为在C语言中,比较运算符是两两进行的,不能进行这样的链式比较。你应该将这个条件分开写,即"a > 0 && a < 40"。然而,在这种情况下,由于你的a,b,c,d初始值都为1,且在每个while循环的开始都会自增,所以这个判断条件总是成立的,这就造成了死循环。

另外,在这个问题中,我们需要找出所有面值10元、5元、2元和1元的组合,使得总值等于100元,这意味着a,b,c,d可能的取值范围应该是0到100,而不是1到40。

修复这个问题后的代码可能如下所示:

  1. #include<stdio.h>

  2. int main() {
  3.     int a=0, b=0, c=0, d=0;
  4.     int n=0;
  5.     while (a <= 100)
  6.     {
  7.         b = 0;
  8.         while (b <= 100)
  9.         {
  10.             c = 0;
  11.             while (c <= 100)
  12.             {
  13.                 d = 0;
  14.                 while (d <= 100)
  15.                 {
  16.                     if (a * 10 + b * 5 + c * 2 + d * 1 == 100)
  17.                     {
  18.                         n++;
  19.                     }
  20.                     d++;
  21.                 }
  22.                 c++;
  23.             }
  24.             b++;
  25.         }
  26.         a++;
  27.     }
  28.     printf("%d\n",n);
  29.     return 0;
  30. }
复制代码


这个代码的运行时间可能会比较长,因为我们需要检查每一个可能的组合,这样的复杂度是O(n^4)。你可以通过一些优化来降低运行时间,例如,我们知道10元、5元、2元和1元的最大数量分别为10, 20, 50, 100,可以根据这个信息来限制循环的范围,从而减少运行时间。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-7-6 09:54:03 | 显示全部楼层
isdkz 发表于 2023-7-6 09:45
你的代码确实存在一个死循环的问题,问题出在你的while循环条件中。在你的代码中,你设定了条件"0

请问已经在定义时就给abcd都赋值了0,为什么还要在每一层循环内给b,c,d再赋值一次0呢
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-7-6 09:55:04 | 显示全部楼层
Aommm 发表于 2023-7-6 09:54
请问已经在定义时就给abcd都赋值了0,为什么还要在每一层循环内给b,c,d再赋值一次0呢

你提出了一个很好的问题。其实在你的循环内再次赋值0,是因为在每次外层循环迭代时,我们需要重置内层循环的计数变量,以确保在每次外层循环迭代时,内层循环都是从0开始的。

举个例子,假设我们只有两层循环,代码如下:

  1. int a=0, b=0;
  2. while (a <= 3)
  3. {
  4.     while (b <= 3)
  5.     {
  6.         printf("a=%d, b=%d\n", a, b);
  7.         b++;
  8.     }
  9.     a++;
  10. }
复制代码


你会发现这段代码只能正确地执行一次b的循环,因为在第一次外层循环结束后,b的值变为了4,没有被重置,所以当a为1、2、3时,内层循环都无法执行。如果我们希望在每次a增加时,都能重新开始b的循环,那么我们就需要在每次开始b的循环时,将b重置为0。

所以,如果我们修改上述代码为:

  1. int a=0, b=0;
  2. while (a <= 3)
  3. {
  4.     b = 0;
  5.     while (b <= 3)
  6.     {
  7.         printf("a=%d, b=%d\n", a, b);
  8.         b++;
  9.     }
  10.     a++;
  11. }
复制代码


这段代码就能够按照我们预期的方式运行了。在每次外层循环迭代时,都会重新开始b的循环。

在你的问题中,由于有4层嵌套循环,我们需要在每一层开始时重置内层循环的变量,确保所有的可能组合都被考虑到。

点评

谢谢您,明白啦  发表于 2023-7-6 10:01
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-10 11:51

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表