有這樣一道智力題:「某商店規定:三個空汽水瓶可以換一瓶汽水。小張手上有十個空汽水瓶,她最多可以換多少瓶汽水喝?」答案是5瓶,方法如下:先用9個空瓶子換3瓶汽水,喝掉3瓶滿的,喝完以後4個空瓶子,用3個再換一瓶,喝掉這瓶滿的,這時候剩2個空瓶子。然後你讓老闆先借給你一瓶汽水,喝掉這瓶滿的,喝完以後用3個空瓶子換一瓶滿的還給老闆。如果小張手上有n個空汽水瓶,最多可以換多少瓶汽水喝?
有一位同學給出了如下圖所示的演算法
那麼問題來了,這樣寫到底正確嗎???????
將上圖**執行一下
1.public classtest02
6.if(x==2)
9.return0;
10. }
11.
12.public static voidmain(string args)
15. }
結果確實是5
換汽水的過程描述如下
1. (拿著空瓶子)手裡有n個空瓶子,0瓶未喝的汽水
2. (換汽水)換n/3個汽水,餘下n%3個空瓶子
3. (喝汽水)喝掉換來的汽水,手裡有n/3+n%3個空瓶子,0瓶未喝的汽水
4. (判斷)如果現在手裡拿的空瓶子》2,執行1
如果手裡拿的空瓶子==2,再換一瓶汽水,結束
手裡拿的空瓶子<2,結束
手裡有10個空瓶子的計算過程如下
現在手裡有的空瓶子
現在手裡有的汽水數
喝在肚子裡的汽水數0
10%3=1
10/3=3
10%3+10/3=40
4%3=1
4/3=1
4%3+4/3=20
現在手裡有的汽水數為0代表把用空瓶換來的汽水喝掉了
最後剩2個空瓶子,還能換一瓶汽水
喝在肚子汽水數 = 3+1+1 = 5
empty(10)-10
= 10+empty(4)-10
= 10+4+empty(2)-10
= 10+4+1-10
根據分析,汽水數應該 = 3+1+1 ,而不是= 10+4+1-10
顯然雖然程式執行的結果和正確答案相同,但是計算過程很可能有問題
上面的分析只是表達原**的計算過程可能有問題,下面我們用手裡20個空瓶子的情況再進一步驗證程式
現在手裡有的空瓶子
現在手裡有的汽水數
喝在肚子裡的汽水數
20%3=2
20/3=6
20%3+20/3=8
8%3=2
8/3=2
8%3+8/3=4
4%3=1
4/3=1
4%3+4/3=2
因為最後剩2個空瓶子,還能再換一瓶汽水
喝在肚子裡的汽水數 = 6+2+1+1 = 10
其實現在問題就來了,10個空瓶的時候,原程式輸出empty(10)-10
那20個空瓶,後面應該減幾呢?
我試了一下,empty(20)-10=23,empty(20)-20=13,和我們算出的答案都不一樣
下面給出兩種程式的寫法,來實現這個問題
public static voidmain(string args)
if(empty == 2)else if(empty < 2)
}a. 定義函式:int soda(intempty)
b. 函式描述:empty代表手裡有的空瓶,返回一共喝了幾瓶汽水
c. 遞迴公式描述:喝總汽水數 = 直接換來的汽水+剩的空瓶還能換的汽水
d. 遞迴公式:soda = empty/3+soda(empty/ 3 + empty % 3)
private static intsoda(intempty)if(empty == 2)return0;1. 賣汽水的老闆真好,2個空瓶都給換汽水}public static voidmain(string args)
2. 小張真能喝汽水
使用drools解決小明喝汽水的問題
問題描寫敘述 1 小明手上有50元錢。2 1元錢能夠買一瓶飲料 3 2個空瓶能夠兌換一瓶飲料 4 問題是 終於小明能夠喝多少瓶飲料 首先。新建m en專案。增加drools依賴 org.drools drools core 6.2.0.final org.drools drools compiler...
思維慣性引發的程式設計問題
為什麼程式要了解思維的障礙,並要練習有意識的加以克服?這裡舉乙個實際發生的問題。寫 像寫作一樣,有時思如泉湧,順著思路就把一段 寫得有模有樣。下面是乙個狀態碼檢查的例子 這種寫法本身並不嚴謹,但這裡要討論是乙個更為嚴重的問題.typedef enum state item state為獲得的狀態 i...
C程式設計的抽象思維 遞迴過程 數集分離問題
問題 給定乙個數集,分離問題要求找到其子集,使所有的數相加等於乙個特定的數。例如,有兩種方法可以分離集合,從而使子集中的額元素相加等於5 第一種方法 選1和4 第二種方法 只選5 相比之下,沒有方法分離集合得到11。編寫乙個函式numberofpartitions,它以乙個整數陣列 陣列長度和目標數...