宙斯下令千天撒豆——潘MM多情巧用循环

编程爱好者

在古希腊,据说宙斯是天界的最高统治者。有一位美丽的潘多拉公主,诸神因妒忌她的美貌,便说服宙斯送给她一个神秘的盒子,并叮嘱她千万别打开那个盒子。然而,有一天,潘多拉终于抵制不住好奇心的诱惑,打开了盒盖,于是,盒内的疾病、痛苦、疯狂等不幸趁机飞出来,传播到了人间。幸亏一位心地善良的天神及时叫她关闭盒子,才留住了承受痛苦的良药:希望、鼓励。

据说在这个盒子中有一种希望豆,她将希望豆发放了三天,希望它能撒播人间。第一天,她把该希望豆中的一半又多一颗发给生活在山上的人们;第二天,把剩下的一半又多一颗发给平原上的人们;第三天最后剩下的一半又多一颗豆豆发给海岛上生活的人们,到第四天一看,只剩颗一个豆豆了,她将这个豆豆永远留在盒子里,也使人们希望永留人间。我们的第一个问题由此而生,希望豆原来究竟有多少颗?

潘多拉撒豆后不久,有农神向宙斯打小报告,潘多拉靠撒希望豆抬升自己的声望,宙斯想了另外一个办法,你不是厉害吗?我令你先撒上十年希望豆试一下,但必须天天发,十年就3650天,看你烦不烦!宙斯为自己的聪明主意而窃喜。第二个问题也出来了:农神要给潘多拉多少希望豆呢?

潘多拉豆解析:

先研究第一个问题,破解潘MM的盒子,还是通过我们前面的五步分析法。

第一步:树梯子

这是最简陋一个图形,请先画上一个“目”字形,也是最基本的一步。

第二步:做头尾

先分析开头和结尾部分,开头是什么呢?题中的已知可输入条件,也就是已知时间顺序最后一天,开头是,第4天豆豆数s4=1。结尾是什么呢?处理完成后的结果,即求第1天的豆豆数(如图1示)。

21-f20-02.jpg
图1

第三步:连头尾

如何将开头和结尾连接起来呢?也就是将第4天和第1天建立联系,问题又可分成三部分(图2),即建立当前天和上前天的关系,它们的关系即“第三天数量/2-1”和第四天相等,因为是已知第四天s4求第三天s3,将关系反过来可用公式s3=2*(s4+1)(如图3),其他的几个关系类似。

21-f20-04.jpg
图2
21-f20-03.jpg
图3

第四步:贴语法

各个语句和具体语言的语法还有一定的差距,根据相应语言,还要再行将相应语句转化(如图4示)。

21-f20-05.jpg
图4

第五步:写代码

下面可以很简单地写代码了。

s4=1

s3=2*(s4+1)

s2=2*(s3+1)

s1=2*(s2+1)

print s1

问题到了这里,好像应该结束了,但我们细看一下上面的句子,特别是中间的三句,像隐含了点什么,意犹未尽。其实我们的问题还没完:有没有更简洁的表达形式呢?

上面的一个小题中,我们用到了四个变量s1~s4,发挥一下,如果将s后的数字去掉,所有的四个变量成了一个,能不能完成我们需要表达的意思呢?

s=1

s=2*(s+1)

s=2*(s+1)

s=2*(s+1)

print s

将所有的标号1234去除后,形式一下子变了,上面的程序中呈现出一种更加简洁的美感来。这个程序和原先的程序会执行出怎样不同的结果呢?通过电脑可以验证,最后得到的结果和前面方式得到的是完全一样的!这就是赋值,潘多拉魔盒的另一面:通过形似,而仍不失神。

我们可以归结到下面的更为简洁的形式来理解赋值,也就是语句i=i+1(i:=i+1)。

语句中的第一个i和第二个i是一个i,但其里面的东西却是不同的,第一个i比第二个i多1。好比我们有一个魔盒(如图5的八角形示),它的名称叫i,原先里面有一个希望豆,现在又加上了一个,第一个盘子里自然就是两个了。如果作为等号,在数学上是完全行不通的;如果作为赋值,在程序界,可以,并且因它的存在而精彩。所以上面的等号不是代表“等于关系”,而是一个将赋值号(=或有些语言中的:=)后面的所有东东放入了赋值号前的i里面的问题。

21-f20-06.jpg
图5

而关于赋值的精彩还在后面,这也是我们编程中的“希望之豆”。了解到这里,我们可以解第二个问题了,农神需要预备多少希望豆呢?年最终要转化成天,十年是3650天,要撒这么多天豆,和撒3天有什么不同吗?通过三天的潘多拉撒豆,我们不难看出,3650天中间将会出现3650条语句(如图6所示),怎么解决呢?可用另外一种方式,那就是循环(如图7),我们变换向电脑描述问题的方式,不再一句一句地和它去对话,而是直接告诉它:请做3650遍吧(如图7)!

21-f20-07.jpg
图6
21-f20-08.jpg
图7

根据图7,可以想象的代码形式如下:

s=1

for i=1 to 3650

s=2*(s+1)

next i

print s

显然,上面的程序是无法执行的,因为真要撒3650天,你可以算一下,希望豆豆的数目将会大到连神仙都害怕,这个数会大到1后面有好几百个0那么大,我们的微机是无法用这个程序完成的。但我们的重点不在这里,所以,可以看一下10天的希望豆是一种什么情况?这是一个有意思的对比,代码如下:

s=1

for i=1 to 10

s=2*(s+1)

next i

print s

上面的代码可以很好地在电脑上执行。美妙的重复规律可以用循环。需要我们注意的是,循环也不是无限制的。

阿兰开讲:

潘多拉魔盒的第一层秘密是:解决问题,认清目标,是解题的第一要务;理清脉络,是解题的关键。而理清脉络的一个有力武器就是时间,时间顺序是一种我们找规律的好工具。编程亦然,看清要编程的问题是编程的第一步,也是基础,还要通过编程的方式来阅读问题,认清努力目标,找出题中的规律。

宙斯的真意是想说:撒三天豆是一种放松,撒千天豆是种惩罚!

幸亏潘多拉魔盒中还蕴藏着一颗更有力的“希望之豆”,它就是我们的赋值语句,即形如s=...s...之类的赋值语句,通过它们,可以传达形似神不同的神奇功效。这颗希望豆传达了顺序程序结构和循环结构之间的关系。

另外,值得我们注意的一点是,“3”这个数字是我们编程中尤其要重视的一个数字,当我们遇到比3大的时候,就要思考是不是还要闷头做下去,遇到超过3的重复的时候,我们首先要想到的是:是否有什么规律,有的话那就用循环,以下命令的口吻来让电脑干活,而不是自己费力地机械地去辛苦地劳作。这可能也就是电脑和我们人类不同的地方吧,让电脑以它擅长的方式去做,人们以自己擅长的方式告诉电脑去做,这也正是程序的意义所在。

但大多数问题,要更好地找出题中蕴藏的规律,只有时间做规律恐怕还不行,怎么办呢?不怕,前人还为我们总结了不少东西,许许多多优秀的科技成果、定理、定律等等,为什么不用呢,那又那怎样利用呢?欲知后事如何,且听下回分解。

小测验:猴子分食桃子

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

19期小测验参考答案:

问题的关键是:地球上哪个地方能够转两个90度角就可以回到原地呢?另外一个就是以颜色出名的熊。两个问题混合到一起猜想,必定是北极点了。所以一定是北极熊,当然是白色的了。