乖财子灵机动苦写万字 唐伯虎讨家教费进困局
编程爱好者
上回讲到孙悟空三打白骨精的故事,现在,再回到五百多年前的中国,看一下一位风流才子的故事,他就是唐伯虎,他曾经收过一个流传千古的学生,因写一个万字而名垂千古。

说起唐伯虎,可谓妇孺皆知。“唐伯虎点秋香” 、“三笑”、“三约牡丹亭”在民间广为流传,然而人们对他知道更多的是“风流才子”的一面。到了他晚年,家境已大不如前,迫不得已,只好卖画为生,而在卖画都不得营生之时,逼不得已,只好为苏州的一个财主当家教。
这个财主非常富有,但几代人都不识字。正在唐伯虎最困难的时候,他请老唐做先生教儿子认字。唐伯虎十分认真地对待他的这份工作,先教他儿子握笔临帖,写了一画,说:“这是‘一’字。”写两画,说:“这是‘二’字。”写三画,又说:“这是‘三’字。”那孩子便喜孜孜地甩下笔,告诉父亲说:“孩儿全会了,孩儿全会了。不要再麻烦先生,多花学费了,把他辞退吧。”财主高兴地照办,婉言把老唐辞退,最令唐伯虎郁闷的是财主儿子必须通过考试后他才能取得工钱。正巧,财主打算宴请一位姓万的朋友,就把写请柬作为儿子的考试题目。可是过了好长时间,也不见他写完,便去催促。谁知孩子气愤地叫道:“天下的姓那么多,为何要姓万!苦得我从早晨写到现在,才写完500画!”
因此可想而知,财主会不会轻易地交给唐伯虎工钱,从此,老唐踏上了讨债之路,最后将财主逼得没办法了,出了一题:银票最大的是100元一张的,此外还有1元、2元和5元面额的,现有一张100元银票,要全换成1元、2元和5元的,必须每种银票至少一张,该怎么做呢,总共又有多少种做法呢?
老唐是读书人,不是算账的。我们的问题也就有了:如何帮才子唐伯虎渡过难关?
伯虎银票解题
伯虎先生的银票问题,拿到现在,就是我们如何兑换零钱的问题。拿一张100元大钞,可以看一下如何兑换成1元、2元和5元面额的,怎么办呢?
我们还是先看一下如何兑换1元的,有100种情况,最少可以兑换1张,最多可以兑换100张;两元的情况差不多,最少是1张,最多则是50张;而五元的最少是1张,最多是20张。怎样将这三大种情况组合到一起呢?
总计有多少种可能的方案呢?下面我们一步步地看,一种种详细地罗列一下看看。从一张1元,一张2元,一张5元开始,直到100张1元,50张2元,20张5元结束,为了便于发现规律,我们最好还是分类有规律地将上面的情况通过列表的形式表达一下。先看一下1元银票1张的情况,总计有50×20即1000种,1元2张的情况有些类似,可以一直到1元100张的情况。
总计是多少种方案呢?我们细心数一下,不是100+50+20种情况,而是100*50*20种情况,在这些情况中,必定有符合老唐方案的,恰好是100元。
这么多的情况,如果每种手工计算,那太麻烦了,最好的办法还是用循环,怎样用呢?用一个循环,好像规律不太好找,那怎么办呢?我们可以忽略一些东西,如图1上面画的大阴影部分仅仅是一大块,加上我们忽略的,题目中总计有100块,只要将前面第一列中的1元情况改成2元情况就出来了,由于其里面的东西是可以暂时忽略的,那忽略里面的东西,可以用一个循环来表达出来。

做出来之后,我们再将做出的外围部分忽略,精力集中到其内部,将5元的细节忽略,又是一个循环,2元的情况是从1到50(如图2所示)。

将图2做出后,还是将精力集中到内部,将忽略的5元部分做出,又是一个循环,从1到20(如图3所示)。

现在100×50×20种方案全都有了,而重点成了我们如何处理每一种了情况了,每一种情况有两种可能,但只会出现一种结果,要么是我们要的,要么不是,条件就是看三种情况组合后的钱数是不是100(如图4所示),也即是money1*1+money2*2+money5*5=100。那第二问如何办呢?

第二问的本质,是对符合题目的方案计数,所以可以另设一变量Ncount,通过它来记录下正确方案的个数,最后将这一数字输出,一切OK(如图所5示)。

有了图,代码也就很简单了,写的时候还要学会忽略,学会从整体出发。
Ncount=0
For money1 = 1 To 100
For money2 = 1 To 50
For money5 = 1 To 20
If money1 + money2 * 2 + money5 * 5 = 100 Then
Print money1, money2, money5
Ncount=Ncount+1
Else
End If
Next money5
Next money2
Next money1
Print Ncount
阿兰开讲
我们祖先造字的时候,选择了一、二、三,而没有造成四条横线式类似的四,可能原因和程序语言中的循环思想差不多,当我们面对多于三的情形时,脑筋的转变和思考是必需的。
我们使用的循环,又可分成两大类:
1.简单的重复
有一个一眼看穿的规律,只要1、2、3就可描绘出来。它是构成循环的基础,一个个循环都是由这样的小部分组成的。
2.复杂的重复
一眼看上去,还看不透,第一个1、2、3…中可能又包含着1、2、3……面对这种看不透的情况,要学会一层层地剥面纱,只要努力细心,总会剥净的,在剥的过程中,还要学会忽略和从整体入手。
编后:程序演义到此,就要告一段落了,循环的出现,使编程中的三种基本结构完整了,正是因为它的出现,程序出现了更加多姿多彩的变化,各种结构套加在一起,形成一派热闹繁荣的景象。我们想通过有趣的故事告诉大家,其实编程就这么简单而有趣!
上期小测验参考答案:
车牌号码为7744,它是88的平方。