程式演義第一七回 伯虎討費進困局,財子靈動苦寫萬

大大老狼發表於2016-07-23

上節講到大文豪功東坡的故事,現在,再回到五百多年前的中國,看一下一位風流才子的故事,他就是唐伯虎,他曾經收過一個流傳千古的學生,因寫一個萬字而名垂千古。本回是一個綜合性題目,綜合的力量在於,不論從哪個方向看,它都不太好解決,但找出任何的一個點,它都很有意思。重點在於,剖開一條自己的路。

enter image description here
圖2.16.1 伯虎賣身契之迷

2.17.1 P17伯虎教書

說起唐伯虎,可謂婦孺皆知。“唐伯虎點秋香” 、“三笑”、“三約牡丹亭”在民間廣為流傳,然而人們更多知道他的是“風流才子”的一面。
唐伯虎是姑蘇趨里人,生於明成化6年庚寅年(1470年),故名唐寅,因排行老大,又稱唐伯虎。史書記載,他出身於一個小商人家庭,父親唐廣德因家道中落在姑蘇吳趨坊皋橋開酒店,當時文徵明父親文林去酒店喝酒,見唐寅才學過人,決定讓唐寅與文徵明一起拜吳門畫派創始人沈周為師。從此唐寅的繪畫天賦得到了充分展現。後與沈周、文徵明、仇英合稱為明四家,與文徵明、祝枝山、徐禎卿合稱為吳中四傑。他的畫風纖柔委婉、清雋生動,尤擅長山水仕女畫,而且兼善書法,詩文俱佳。唐寅家住今蘇州城北桃花塢,故自稱桃花塢主,曾作《桃花庵歌》,自比採花仙人。他自幼性格不羈,稱己為“江南第一風流才子”。29歲時中鄉試第一,人稱唐解元。會試時因牽涉科場舞弊案而被革黜,就此唐寅絕意仕途,遊歷名山大川,致力繪畫。正德9年(1514年)他被明宗室寧王以重金徵聘到南昌,後發現身陷寧王政治陰謀之中,遂佯裝瘋癲,脫身迴歸故里,但家況已大不如前,逼不得已,只好賣畫為生,而在賣畫都不得營生之時,逼不得已,為一財主教書。 蘇州的這個財主,非常富有,但幾代人都不識字。正在唐伯虎最困難的時候,他請老唐做先生教兒子認字。唐伯虎十分認真地對待他的這份工作,先教他兒子握筆臨帖,寫了一劃,說:“這是‘一’字。”寫兩劃,說:“這是‘二’字。”寫三劃,又說:“這是‘三’字。”那孩子便喜孜孜地甩下筆,告訴父親說:“孩兒全會了,孩兒全會了。不要再麻煩先生,多花學費了,把他辭退吧。”財主高興地照辦,婉言把老唐辭退,最令他鬱悶的是必須通過考試後才能取得工錢。正巧,財主打算宴請一位姓萬的朋友,就讓兒子寫請束以做為考試。可是過了好長時間,也不見他寫完,便去催促。誰知孩子氣憤地叫道:“天下的姓那麼多,為何要姓萬!苦得我從早晨寫到現在,才寫完500劃!”
因此可想而知,財主會不會輕易地交給唐伯虎工錢,由此,老唐踏上了討債之路,最後將地主逼得沒辦法了,出了一題:銀票最大的是100元一張的,還有1元、2元和5元的,現有一張百元銀票,要全換成1元、2元和5元的,必須每種銀票至少一張,該怎麼做呢?
老唐是讀書人,不是算賬的。我們的問題也就有了:如何幫才子唐伯虎渡過難關?

2.17.2 伯虎銀票解題
伯虎先生的銀票問題,拿到現在,就是我們如何兌換零錢的問題。拿一張百元大鈔,可以看一下如何兌換1元的,這個問題,我們閉上眼睛都能解出來,但問題不僅僅是1元的,還有2元和5元,怎麼辦呢?
我們還是先看一下如何兌換1元的,有100種情況,最少可以兌換1張,最多可以兌換100張;兩元的情況差不多,最少是1張,最多則是50張;而五元的最少是1張,最多是20張。怎樣將這三大種情況組合到一起呢?
總計有多少種可能的方案呢?100+50+20還是其他呢?下面我們一步步地看,一種種詳細地羅列一下看看。從1張一元,1張兩元,1張五元開始,直到100張一元,50張二元,20張五元結束,為了便於發現規律,我們最好還是分類有規律地將上面的情況通過列表的形式表達一下。
enter image description here

總計是多少種方案呢?我們細心數一下,不是100+50+20種情況,而是100*50*20種情況,在這些情況中,必定有符合老唐的方案,恰好是100元。 這麼多的情況,如果一種種手工計算,那太麻煩了,最好的辦法還是用迴圈,怎樣用呢?用一個迴圈,象規律不太好找,那怎麼辦呢?我們可以做一個忽略,大陰影部分有三大塊,加上我們忽略的,總計有100塊,並且其值是從1到100的,由於其裡面的東西是同樣的,那忽略裡面的東西,可以用一個迴圈來表達出來(如圖1)。 enter image description here
圖1
做出來之後,我們再將做出的外圍部分忽略,精力集中到其內部,將五元的細節忽略,又是一個迴圈,2元的情況是從1到50(如圖2示)。
enter image description here
圖2
將圖2做出後,還是將精力集中到內部,將忽略的五元部分做出,又是一個迴圈,從1到20(如圖3示)。
enter image description here
圖3
現在100X50X20種方案全都有了,現在的重點,成了我們如何處理每一種了,每一種有兩種可能,但只會同現一種結果,要麼是我們要的,要麼不是,條件就是看三種情況組合後的錢數是不是100(如圖4示),也即是money1*1+money2*2+money5*5=100。那第二問如何辦呢?

enter image description here

圖4
第二問的本質,是對符合題件的方案計數,所以可以另設一變數Ncount,通過它來記錄下正確方案的個數,最後將這一數字輸出,一切OK(如圖5示)。
enter image description here
圖5

有了圖,程式碼也就很簡單了,寫的時候還要學會忽略,學會從整體出發。

enter image description here

2.17.3 阿蘭開講

我們祖先造字的時候,選擇了一、二、三,而沒有造成四條橫線式“ ”類似的四,可能原因和程式語言中的迴圈思想差不多,當我們面對多於三的情形時,腦筋的轉變和思考是必需的。
我們使用的迴圈,又可分成兩大類:
1、簡單的重複
有一個一眼看穿的規律,只要1,2,3就可描繪出來。它是構成迴圈的基礎,一個個迴圈都是由這樣的小部分組成的。
2、複雜的重複
一眼看上去,還看不透,除了有1,2,3等等,第一個1,2,3…中可能又包含著1,2,3…,面對這種看不透,要學會一層層地剝面紗,只要努力細心,總會剝淨的,在剝的過程中,還要學會忽略和從整體入手。
程式演義到此,就要告一段落了,迴圈的出現,使程式設計中的三種基本結構出全了,正是因為它的出現,程式出現了更加多姿多彩的變化,各種結構套加在一起,形成一派熱鬧繁榮的景象。我們想通過有趣的故事告訴大家,其實程式設計就這麼簡單而有趣!

2.17.4 小測驗:消失的1元錢
3個人住宿時,每人10元錢,將30元錢交給服務員後,再到會計那裡去,會計找回5元,服務員中間私吞了2元錢,只還給他們3元錢。
3人分3元錢,一個退回1元錢,合計每人付了9元錢,加在一起共27元,再加上服務員私吞的2元,一共29元,而付賬時是30元,那一元錢到哪裡去了?

相關文章