递归解猴子分香蕉问题

 一、题干

二、思路

该题具有比较明显的递归特征,从逆向开始,最终分成5堆一个不剩,可设为最终的每堆里有n个香蕉,则第四次猴子分完后,留给第五只猴子的香蕉数量是5\cdot n

第四只猴子拿到的香蕉,是经第三只猴子分完后剩下的,往回推算即\left ( 5\cdot n \right )\cdot \frac{5}{4}+4。这里的\frac{5}{4},因为分成五堆后,第四只猴子拿走了属于自己的一份,只剩下四堆,从四堆往五堆算,就是乘上4/5。

第三只猴子拿到的香蕉,是经第三只猴子分完后剩下的,往回推算即\left ( 5\cdot n\cdot \frac{5}{4}+4 \right )\cdot \frac{5}{4}+3,括号内为上一段的结果。

以此类推,具有很明显的递归特征。故可用递归解决。

三、实例

#include <stdio.h>
 /*思路为遍历1-10000内所有的数字,用自定义的num函数判断其是否符合题意
n为遍历的数,i用来计数递归,默认为1(主函数中),也可以理解成第几只猴子开始分香蕉,或者分的香蕉的剩余数目(余数)*/
int num(int n,int i) {
	int temp;    //声明中间量,无实际意义
	if (0 == (n - i) % 5 && n != 0) {   //条件判断    
		if (5 == i ) {					//退出递归的条件,即最终递归次数为5(即这个数n刚好被五个猴子分),同时分到最后能被5整除,退出递归,返回1
			return 1;					//返回1,表示符合题意
		}
		else {							//满足题意,但是i没到5,也就是还没轮到第五只猴子分,则继续递归
			temp = 4 * (n - i) / 5;		//a为该猴子吃完后、藏好后,还剩下的香蕉数量
			return num(temp, i + 1);
		}
	}
	else {								//若香蕉个数n,无法满足题意,即减去剩余香蕉数后无法被五整除,则返回0(表示不符合题意
		return 0;
	}

}
int main() {
	int a = 0;
	int i = 1;
	while (i<10000){	               
		a = num(i,1);					//将遍历的数塞入自定义的num函数,判断是否符合题意,符合题意,num函数返回1,不符合,num函数返回0
		if (a) {                        //判断返回值是否为0,不为0,则输出答案
			printf("%d \n",i);
		}
		i++;
	}
}

四、结果

可知最小值为3141,需要注意在num函数中第三行,若不加n != 0,的与判定条件,会输出16这个答案。其不符合题意的地方在于,分到第五只猴子后的香蕉个数为0,0也恰好能被5分成5份,每份的个数为0.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值