鱼C论坛

 找回密码
 立即注册
查看: 758|回复: 4

[已解决]考察英国货币面值的组合问题(以及为什么我的数组传不进去)

[复制链接]
发表于 2023-6-25 16:22:02 | 显示全部楼层 |阅读模式
10鱼币
/*
在英国,货币是由英镑 £,便士 p 构成的。一共有八种钱币在流通:

1p, 2p, 5p, 10p, 20p, 50p, £1 (100p) 和 £2 (200p).
要构造 £2 可以用如下方法:

1×£1 + 1×50p + 2×20p + 1×5p + 1×2p + 3×1p

允许使用任意数目的钱币,一共有多少种构造 £2 的方法?
*/

//总体思路是判断一种货币可能出现的情况(主函数判断哪种货币,从大到小)
//利用递归完成,200-该货币(余额)的情况
#include<stdio.h>

int array[8]={1,2,5,10,20,50,100,200};
int count=0;//定义一个全局变量,用来统计数量

void Count(int m,int sum,int *array,int a)
{
        if(array[m]!=array[0])//没有 只剩下一种货币供选择。
        {
                if(a==1)
                {
                        for(int k=1;k<=sum/array[m];k++)//第一次不能取0;其他时候可以取。
                  {
                        if(sum-k*array[m]==0)//如果余额为零
                        {
                                count++;
                                return;
                        }
                        else//对余额情况进行递归
                        {
                                Count(m-1,sum-k*array[m],array,0);
                        }
                  }
                }
                else
                {
                        for(int k=0;k<=sum/array[m];k++)//第一次不能取0;其他时候可以取。
                  {
                        if(sum-k*array[m]==0)
                        {
                                count++;
                                return;
                        }
                        else
                        {
                                Count(m-1,sum-k*array[m],array,0);
                        }
                  }
                }
        }
        else
        {
                count++;
                return;
        }
}


int main(void)
{
        for(int i=7;i>=1;i--)
        {
                Count(i,200,array,1);
        }
       
        count++;//把全部是1的加入
       
        printf("一共有%d种构造 面额为200 的方法",count);
       
        return 0;
}
最佳答案
2023-6-25 16:22:03
你的代码大体上是正确的,主要思路就是递归处理各种货币组合的问题。这里我对你的代码做了一些微小的修改,以增加代码的可读性,并修复了一些可能导致错误的地方。这是修改后的代码:

  1. #include<stdio.h>

  2. int array[8] = {1, 2, 5, 10, 20, 50, 100, 200};
  3. int count = 0;

  4. void Count(int m, int sum, int *array)
  5. {
  6.     if(m >= 0) {
  7.         for(int k = 0; k <= sum / array[m]; k++) {
  8.             if(sum - k * array[m] == 0) {
  9.                 count++;
  10.             }
  11.             else {
  12.                 Count(m - 1, sum - k * array[m], array);
  13.             }
  14.         }
  15.     }
  16. }

  17. int main(void)
  18. {
  19.     Count(7, 200, array);
  20.     printf("一共有%d种构造 面额为200 的方法", count);
  21.     return 0;
  22. }
复制代码

这个程序的主要工作就是在函数  Count  中进行,它采用了递归的方式处理所有可能的货币组合。注意,在递归调用  Count  函数时,我并没有用到你在原始代码中的  a  参数。对于每一种面值的货币,我们都尝试用不同数量的它来组合,如果剩余的面额(sum - k * array[m])等于0,就说明我们找到了一种组合方式,计数器  count  就会加1。如果剩余的面额不等于0,我们就递归地尝试用更小的面值的货币来组合剩余的面额。

这个程序运行的效率可能不会很高,因为它需要尝试所有可能的货币组合。如果面额较大,可能会花费较长的时间。但是对于面额为200的情况,这个程序应该是可以在合理的时间内得出结果的。

最佳答案

查看完整内容

你的代码大体上是正确的,主要思路就是递归处理各种货币组合的问题。这里我对你的代码做了一些微小的修改,以增加代码的可读性,并修复了一些可能导致错误的地方。这是修改后的代码: 这个程序的主要工作就是在函数 Count 中进行,它采用了递归的方式处理所有可能的货币组合。注意,在递归调用 Count 函数时,我并没有用到你在原始代码中的 a 参数。对于每一种面值的货币,我们都尝试用不同数量的它来组合,如果剩余的 ...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-6-25 16:22:03 | 显示全部楼层    本楼为最佳答案   
你的代码大体上是正确的,主要思路就是递归处理各种货币组合的问题。这里我对你的代码做了一些微小的修改,以增加代码的可读性,并修复了一些可能导致错误的地方。这是修改后的代码:

  1. #include<stdio.h>

  2. int array[8] = {1, 2, 5, 10, 20, 50, 100, 200};
  3. int count = 0;

  4. void Count(int m, int sum, int *array)
  5. {
  6.     if(m >= 0) {
  7.         for(int k = 0; k <= sum / array[m]; k++) {
  8.             if(sum - k * array[m] == 0) {
  9.                 count++;
  10.             }
  11.             else {
  12.                 Count(m - 1, sum - k * array[m], array);
  13.             }
  14.         }
  15.     }
  16. }

  17. int main(void)
  18. {
  19.     Count(7, 200, array);
  20.     printf("一共有%d种构造 面额为200 的方法", count);
  21.     return 0;
  22. }
复制代码

这个程序的主要工作就是在函数  Count  中进行,它采用了递归的方式处理所有可能的货币组合。注意,在递归调用  Count  函数时,我并没有用到你在原始代码中的  a  参数。对于每一种面值的货币,我们都尝试用不同数量的它来组合,如果剩余的面额(sum - k * array[m])等于0,就说明我们找到了一种组合方式,计数器  count  就会加1。如果剩余的面额不等于0,我们就递归地尝试用更小的面值的货币来组合剩余的面额。

这个程序运行的效率可能不会很高,因为它需要尝试所有可能的货币组合。如果面额较大,可能会花费较长的时间。但是对于面额为200的情况,这个程序应该是可以在合理的时间内得出结果的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-6-25 16:30:40 | 显示全部楼层
关于数组无法传递的问题,需要先了解一下具体情况。在这段代码中,你定义了一个名为 “array” 的数组,但是并没有明确指明其大小,也就是说,它的长度无法被编译器自动检测出来。因此,在进行调用时,就需要通过其他手段来告知函数数组的长度。

有两种方法可以解决这个问题:

1. 在函数参数中显式地传递数组长度

这种方式要求你修改 Count 函数的声明,将其第三个参数改为一个指向 int 类型变量的指针,并添加一个表示数组长度的整型参数,可以使用如下代码实现:


  1. void Count(int m, int sum, int *array, int len, int a)
复制代码


然后在调用的时候,在 Count 函数中增加一行代码,对数组指针进行偏移,即可获得数组长度,例如:

  1. Count(i, 200, array + i, 8 - i, 1);
复制代码


2. 使用全局变量

由于在这个程序中,数组的长度(8)是已知的,可以通过定义一个全局变量来获取这个值:

  1. int len = 8; // 定义一个全局变量保存数组长度

  2. void Count(int m,int sum,int *array,int a)
  3. {
  4.     //...
  5. }

  6. // 在 main 函数中使用 len 来代替具体的长度值
  7. for(int i=7;i>=1;i--)
  8. {
  9.     Count(i,200,array,len-i,1);
  10. }
复制代码

总之,无论选择哪种方法,在调用函数时都需要确保正确传递进数组的长度。

求最佳答案
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-6-25 21:27:30 | 显示全部楼层
isdkz 发表于 2023-6-25 16:22
你的代码大体上是正确的,主要思路就是递归处理各种货币组合的问题。这里我对你的代码做了一些微小的修改, ...

谢谢大佬,我的逻辑菜的像一坨死。那个递归的作用被我忽视了好多,运行效率不高是采用了递归吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-6-25 22:20:48 | 显示全部楼层
好吧,时间复杂度太大了,去动态规划了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-4 06:12

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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