Aommm 发表于 2023-7-6 09:42:04

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

可以看懂用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:42:19

您使用的while循环存在一些问题,导致了死循环。问题在于您没有正确的更新循环条件的值,从而导致循环无法结束。以下是修正后的代码:

c
#include <stdio.h>

int main() {
    int a = 1, b = 1, c = 1, d = 1;
    int n = 0;

    while (a <= 40) {
      b = 1;
      while (b <= 40) {
            c = 1;
            while (c <= 40) {
                d = 1;
                while (d <= 40) {
                  if (a + b + c + d == 40 && a 10 + b 5 + c 2 + d 1 == 100) {
                        n++;
                  }
                  d++;
                }
                c++;
            }
            b++;
      }
      a++;
    }

    printf("%d\n", n);
    return 0;
}


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

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

isdkz 发表于 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。

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

#include<stdio.h>

int main() {
    int a=0, b=0, c=0, d=0;
    int n=0;
    while (a <= 100)
    {
      b = 0;
      while (b <= 100)
      {
            c = 0;
            while (c <= 100)
            {
                d = 0;
                while (d <= 100)
                {
                  if (a * 10 + b * 5 + c * 2 + d * 1 == 100)
                  {
                        n++;
                  }
                  d++;
                }
                c++;
            }
            b++;
      }
      a++;
    }
    printf("%d\n",n);
    return 0;
}


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

Aommm 发表于 2023-7-6 09:54:03

isdkz 发表于 2023-7-6 09:45
你的代码确实存在一个死循环的问题,问题出在你的while循环条件中。在你的代码中,你设定了条件"0

请问已经在定义时就给abcd都赋值了0,为什么还要在每一层循环内给b,c,d再赋值一次0呢

isdkz 发表于 2023-7-6 09:55:04

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

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

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

int a=0, b=0;
while (a <= 3)
{
    while (b <= 3)
    {
      printf("a=%d, b=%d\n", a, b);
      b++;
    }
    a++;
}


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

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

int a=0, b=0;
while (a <= 3)
{
    b = 0;
    while (b <= 3)
    {
      printf("a=%d, b=%d\n", a, b);
      b++;
    }
    a++;
}


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

在你的问题中,由于有4层嵌套循环,我们需要在每一层开始时重置内层循环的变量,确保所有的可能组合都被考虑到。
页: [1]
查看完整版本: 某人想将手中的一张面值100元的人民币换成10元、5元、2元和1元面值的票子。要求换...