鱼C论坛

 找回密码
 立即注册
查看: 1470|回复: 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。

修复这个问题后的代码可能如下所示:
#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,可以根据这个信息来限制循环的范围,从而减少运行时间。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 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 [i] 10 + b [/i] 5 + c [i] 2 + d [/i] 1 == 100) {                        n++;                    }                    d++;                }                c++;            }            b++;        }        a++;    }    printf("%d\n", n);    return 0;}
在修正后的代码中,每个内层循环都在开始时将循环变量重置为初始值。同时,我们在每个循环结束后递增循环变量的值,确保循环能够逐渐向终止条件靠近。这样就可以正确地计算出符合要求的换钱方式的数量了。

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

点评

谢谢!  发表于 2023-7-6 10:02
想知道小甲鱼最近在做啥?请访问 -> 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。

修复这个问题后的代码可能如下所示:
#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,可以根据这个信息来限制循环的范围,从而减少运行时间。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

请问已经在定义时就给abcd都赋值了0,为什么还要在每一层循环内给b,c,d再赋值一次0呢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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层嵌套循环,我们需要在每一层开始时重置内层循环的变量,确保所有的可能组合都被考虑到。

点评

谢谢您,明白啦  发表于 2023-7-6 10:01
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-12-24 08:33

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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