编程小博士(27)

软件世界

  问:小博士,我今天碰到了一个“猴子分食桃子”的难题:五只猴子采得一堆桃子,猴子彼此约定隔天早起后再分食。不过,就在半夜里,一只猴子偷偷起来,把桃子均分成五堆后,发现还多一个,它吃掉这个桃子,并拿走了其中一堆。第二只猴子醒来,又把桃子均分成五堆后,还是多了一个,它也吃掉这个桃子,并拿走了其中一堆。第三只,第四只,第五只猴子都依次如此分食桃子。那么桃子数最少应该有几个呢?

  想了半天,也理不出头绪。感觉上应该有专门的解题方法吧,你能介绍一种专门解决这类问题的算法吗?

  小博士:算法就是对某类特定问题的解题步骤。算法有许多种,最简单的无非是下面的六种:递推法、贪心法、列举法、递归法、分治法和模拟法。刚听名字挺吓人的,其实有些方法我们平常都见过。这些算法当中,最简单的莫过于递推算法了。而它刚好能解决你说的“猴子分食桃子”的问题。

  什么是递推法

  递推法这种解题方法其实在我们编程的过程中用得很多,只不过没有将它上升到理论的高度罢了。所谓递推法,就是找出和时间先后相联系或和数的大小相联系的步骤,上一步和下一步与数字的增大或减小有一定的联系。我们要么从前向后(或从小到大)推导,也可从后向前(或从大到小)推导。由此得出两种推导方法:顺推法和倒推法。再来看看你说的问题。

  编程简析

  怎样编程呢?先要找一下第N只猴子和它面前桃子数的关系。如果从第1只开始往第5只找,不好找,但如果思路一变,从第N到第1去破解,可得出下面的推导式:

  第N只猴 第N只猴前桃子数目

  5 s5=x

  4 s4=s5*5/4+1

  3 s3=s4*5/4+1

  2 s2=s3*5/4+1

  1 s1=s2*5/4+1

  s1即为所求。上面的规律中只要将s1-s5的下标去掉:

  s=x

  s=s*5/4+1

  s=s*5/4+1

  s=s*5/4+1

  s=s*5/4+1

  所以可以用循环语句加以解决。

  综观程序的整体结构,最外是一个循环,因为循环次数不定,可以使用While循环,其结束条件则是找到第一个符合条件的数。为了做出上面while循环的结束条件,还需进一步分析上述规律的特点,要符合题目中的要求,s1-s4四个数必须全部为整数,这个可作为条件。具体实现请参看源程序。

  源程序下载地址:http://www.cpcw.com/27/taozi.txt

  小结

  上面应用的推导方法就是倒推法。生活中的更多问题采用顺推法就可得到,也即从1-N,但不论倒推还是顺推,能递推并解出问题是我们的本意。