算法:猴子分桃
问题描述:
最近看到的一道java练习题,题目描述为:
“五猴分桃:有五只猴子分一堆桃,平均分配以后多出一只.最后他们各自回家睡觉决定第二天再分.晚上一只猴子偷偷过来,先吃掉一只桃,再平均分成五份,拿走了他自己的一份.第二只猴子也过来这样做了.直到第五只猴也这样做了.问:最初,这堆桃子最少有几只?此时第五只猴子得到多少桃子?”
解题思路:
这一题可以用数学思想解,解法如下:
设开始有x个桃子,我们把x写成(x+4)-4. 第一个猴子来了,吃掉1个,还有桃子 (x+4)-4-1=(x+4)-5,这时恰好可分成5份,每份的桃子数为 [(x+4)-5]/5=(x+4)/5-1 (x+4)/5必须为整数,所以(x+4)是5的倍数,第一个猴子藏掉一份后,剩下的桃子为:(4/5)×[(x+4)-5]=(4/5)×(x+4)-4 同样,第二个猴子来了,一吃一藏之后,剩下的桃子数为 (4/5)×[(4/5)×(x+4)-5] 由于(4/5)×(4/5)×(x+4)是整数,故(x+4)应是5×5=25的倍数,如此一来五个猴子一吃一藏,恰好剩下 (4/5)×(4/5)× (4/5)×(4/5) ×(4/5) ×(x+4)-5个桃子,故(x+4)必须是5×5×5×5×5的倍数,即x+4=5^5 所以:x=3125-4=3121 即开始最少有3121个桃子.
即每次猴子分的桃子数量为:x=x-(x-1)/5-1 == 4/5(x-1)
用java解为:
public class 猴子分桃 {
public static void main(String[] args) {
int n=1;
int m=0;
int flag=1;
int monkeyNum=5;
while(true){
flag=1;
m=monkeyNum*n+1;
for(int i=monkeyNum;i>=1;i--){
if(m%(monkeyNum-1)==0){
m=m/(monkeyNum-1)*monkeyNum+1;
flag++;//计算多少次的桃子数量被4整除
}
else
break;
}
if(flag==monkeyNum)
break;
n++;
}
System.out.println("开始的桃子数至少是:"+m);
System.out.println("此时第五只猴子得到的桃子数为:"+n);
}
}
总结:
这题在书上看到的,困住我了几个小时,其中“计算多少次的桃子数量被4整除”的函数体中的代码一直看不懂为什么,调试也不看出思路,就没想着用数学公式推算,哎。。。怪不得网上一直有人说搞算法的数学头脑要好。