C语言每日一练——第57天:递归解决分鱼问题
C语言每日一练
2021年11月13日
文章目录
- 题目描述
- 分析
- 代码实现
- 运行结果
- 网上参考
题目描述
A、B、C、D、E这5个人合伙夜间捕鱼,凌晨时都已经疲惫不堪,于是各自在河边的树丛中找地方睡着了。第二天日上三竿时,A第一个醒来,他将鱼平分为5份,把多余的一条扔回河中,然后拿着自己的一份回家去了;B第二个醒来,但不知道A已经拿走了一份鱼,于是他将剩下的鱼平分为5份,扔掉多余的一条,然后只拿走了自己的一份;接着C、D、E依次醒来,也都按同样的办法分鱼。问这5人至少合伙捕到多少条鱼?每个人醒来后所看到的鱼是多少条?
分析
这题和我在前面做到的《C语言每日一练——第48天:五猴分桃问题》几乎一模一样,只不过是换了层皮,把分桃子变成了分鱼。
虽然题目相同,但上次我并没用到递归,所以再做一遍也说得过去。
思路:
无论是使用递归还是用循环,其判断逻辑都一样。我们可以考虑使用正推法
或倒推法
,
- 顺推,即先假设总共捕鱼数,然后从
A
–>E
的顺序顺推,如果满足:
B = A / 5 * 4 - 1, 且 A mod 5 = 0 (mod表示取余)
C = B / 5 * 4 - 1, 且 B mod 5 = 0
D = C / 5 * 4 - 1, 且 C mod 5 = 0
E = D / 5 * 4 - 1, 且 D mod 5 = 0
E mod 5 = 0
则此时的A的值即为总鱼数
- 倒推,即先假设E分完鱼后剩下的鱼数量为
n
,然后从E
–>A
的顺序倒推,如果满足:
E = n / 4 * 5 + 1, 且 n mod 4 = 0 (mod表示取余)
D = E / 4 * 5 + 1, 且 E mod 4 = 0
C = D / 4 * 5 + 1, 且 D mod 4 = 0
B = C / 4 * 5 + 1, 且 C mod 4 = 0
A = B / 4 * 5 + 1, 且 B mod 4 = 0
则此时的A的值即为总鱼数。
但是在第48天的五猴分桃问题中,已经得出结论:倒推法只要循环判断64
次,而顺推要循环判断624
次,所以这里我只用倒推法进行递归求解。
具体步骤:
先设n
为4,定义一个递归函数int func(int num, int sum)
, 其中num
指递归层数(从E开始,最多5层),sum
为该层的总鱼数(如第一层时,渔夫E进行分鱼,他能分的鱼数sum
为n/4*5+1
)。主函数调用func(5, n)
进行递归判断,如果返回一个非0数字,即为该题结果,如果是0,说明n
值不满足题目条件,增大n
值继续循环判断。
代码实现
#include <stdio.h>void print_func(int n); //打印每个人看到的鱼数量/*** @brief 递归函数* @param num 递归序号(E->A,对应5->1)* @param sum 鱼的数量* @return 0:不满足条件*/
int func(int num, int sum)
{if(num < 1)return sum;else{if(sum % 4 != 0){return 0; //不满足条件}else{sum = sum / 4 * 5 + 1;return func(num - 1, sum);}}
}int main()
{int n = 0, ret = 0;for(n = 4; n < 10000; n+=4){ret = func(5, n); //从E开始递归if(ret){printf("至少捕了%d条鱼\n", ret);print_func(n); //打印每个人看到的鱼数量return 0;}}printf("n的范围太小\n");return 0;
}//打印每个人看到的鱼数量
void print_func(int n)
{int i = 0;char names[5] = {'A', 'B', 'C', 'D', 'E'};for(i = 0; i < 5; i++){n = n / 4 * 5 + 1;printf("%c醒来看到%d条鱼\n", names[4 - i], n);}
}
运行结果
网上参考
原文链接——http://c.biancheng.net/cpp/html/3378.html
具体思路原文讲得很详细,感兴趣的可以去看看。
他选择的是顺推,从A开始递归:
#include<stdio.h>
/*分鱼递归函数*/
int fish(int n, int x)
{if((x-1)%5 == 0){if(n == 1)return 1; /*递归出口*/elsereturn fish(n-1, (x-1)/5*4); /*递归调用*/}return 0; /*x不是符合题意的解,返回0*/
}
int main()
{int i=0, flag=0, x;do{i=i+1;x=i*5+1; /*x最小值为6,以后每次增加5*/if(fish(5, x)) /*将x传入分鱼递归函数进行检验*/{flag=1; /*找到第一个符合题意的x则置标志位为1*/printf("五个人合伙捕到的鱼总数为%d\n", x);}}while(!flag); /*未找到符合题意的x,继续循环,否则退出循环*/return 0;
}
C语言每日一练——第57天:递归解决分鱼问题相关推荐
- 基础学习——C语言递归解决分鱼问题
如有小伙伴想学习C语言基础,可以进群731871503进行交流学习,提升编程,共同进步 问题描述 A.B.C.D.E这5个人合伙夜间捕鱼,凌晨时都已经疲惫不堪,于是各自在河边的树丛中找地方睡着了.第二 ...
- C语言-递归解决分鱼问题。
A.B.C.D.E五个人在某天夜里合伙去捕鱼,到凌晨时疲惫不堪,于是各自找地方睡觉. 第二天A醒来,他将所有的鱼分成5份,把多余的一条鱼扔掉,拿走自己的一份. B醒来,也将剩下的鱼分为5份,把多余的一 ...
- 6 获取数组中最小值_C语言每日一练8——数组中最大值和最小值
题目: 利用指针函数,求某数组中的最大值和最小值. 实现代码: /* ================================================================= ...
- C语言每日一练——第85天:三色球问题
C语言每日一练 2022年3月8日 文章目录 题目描述 问题分析 代码实现 运行结果 网上参考 题目描述 一个口袋中放有12个球,已知其中3个是红的,3个是白的,6个是黑的,现从中任取8个,问共有多少 ...
- C语言每日一练——第73天:谁是窃贼问题
C语言每日一练 202年1月8日 文章目录 题目描述 问题分析 代码实现 运行结果 网上参考 题目描述 警察审问4名窃贼嫌疑犯.现在已知,这4人当中仅有一名是窃贼,还知道这4个人中的每个人要么是诚实的 ...
- C语言每日一练——第35天:打印菱形
C语言每日一练 2021年10月13日 题目描述 输入菱形的高度n(必须为奇数),即正中间星号的个数,打印出用星号组成的菱形 分析 要打印菱形,先要构想要打印的图形样子,就比如下图这种: 我们可以根据 ...
- C语言每日一练——第28天:要求输出国际象棋棋盘
C语言每日一练 2021年10月6日 题目描述 要求输出国际象棋棋盘 分析 先看看国际象棋的棋盘的长相: 可以看出,国际象棋棋盘呈正方形,里面包含8x8总共64个小方格,它们黑白相间.要想在控制台输出 ...
- C语言每日一练——第10天:求一个矩阵主对角线及副对角线元素之和
C语言每日一练 2021年9月18日 题目描述 求一个矩阵主对角线及副对角线元素之和 分析 在数学中,矩阵(Matrix)是一个按照长方阵列排列的复数或实数集合,矩阵是高等代数学中的常见工具,也常见于 ...
- C语言每日一练——第1天:字母大小写转换
C语言每日一练 2021年9月9日 本人C语言菜鸟,最近工作中频频出现C语言小错误,遂决定使用笨方法提高我的C语言水平,坚持每天一个C语言小练习,养成C语言手感,从此让编程成为习惯. 题目描述 从键盘 ...
最新文章
- LeetCode 1224. 最大相等频率(哈希)
- ECCV 2020 大规模实例分割挑战赛(LVIS Challenge)冠军方案
- BW作为源系统连接时,激活DSO或其他模型时提示8*数据源不存在,无法激活
- MFC 消息映射表和虚函数实现消息映射到底谁的效率高
- 一个很方便使用十六进制的颜色值的宏
- 如何使用Python进行投资收益和风险分析
- 2进制快速转换为16进制
- cannot load facet kotlin
- 跨境卖家:如何让海外KOL营销达到理想效果?
- winXP系统在“我的电脑”里打不开FAT32的U盘(8G)的一种解决办法
- 10-3 德扑,股票演绎法,练习量是个要命的问题
- 邮票面值设计java,[蓝桥杯][算法提高VIP]邮票面值设计 (C++代码)
- 10个优秀的AI艺术生成器
- python小游戏毕设 打地鼠小游戏设计与实现 (源码)
- 智能电子棋盘产品分析
- @程序员,这四个学习建议值得收藏
- 山西省初中计算机教案,初中信息教学计划
- 30万用户的社交电商工具被微信封禁,域名为什么那么重要?
- 网页错误代码代表的含义 400、401、403、404、500
- banq修复_设计模式builder(Banq)