猴子分桃


猴子分桃的故事大體有兩種描述:

描述 1 :五只猴子分桃。半夜,第一只猴子先起來,它把桃分成了個數相等的五堆,多出一只;於是,它吃掉了一個,拿走了一堆。第二只猴子起來一看,只有四堆桃,於是把四堆合在一起,分成相等的五堆,又多出一個;然后,它也吃掉了一個,拿走了一堆。剩下的三只猴子也都是這樣分的。問:這堆桃至少有多少個?

描述 2 :海灘上有一堆桃子,五只猴子來分。第一只猴子把這堆桃子平均分為五份,多了一個,這只猴子把多的一個扔入海中,拿走了一份。第二只猴子把剩下的桃子又平均分成五份,又多了一個,它同樣把多的一個扔入海中,拿走了一份。第三、第四、第五只猴子都是這樣做的,問海灘上原來最少有多少個桃子?

分析

程序猿一般這樣看問題:總之桃子數目是整數,me 就從 1 開始試,然后分給猴子們,如果可以按題目要求的分法(去掉 1 個然后平均分 5 份,剩下 4 份)分 5 個猴子不就可以了 ? 真是不動腦筋的思考方案呀,尼瑪 ! 不過這的確是一種萬能的解決方案,對於本題來說,程序也不會運行很久。

現在從一個非程序猿的角度看問題。這里主要是要捕捉到它們的數量關系。

假設第二個猴子拿了 x2 個桃子,第三個猴子拿了 x3 個,那么有這么個關系: 4 x2 = 5 x3 + 1 ,這是類似於 4 a = 5 b + 1 的式子。毫無疑問的是 a 、b 都是整數了。4 a = 5 b + 1 = 4 b + (b + 1),那么可想而知 b + 1 = 4 k,於是有:

a = 5 k - 1  b = 4 k - 1

因為 (x1, x2), (x2, x3), (x3, x4)(x4, x5) 均滿足類似於 4 a = 5 b + 1 的式子,也自然滿足上面的 a, b 關系。假設對應的 k 分別是k1  k2  k3  k4,根據 x2 = 4 k1 - 1 = 5 k2 - 1 ,可以得出 k1 : k2 = 5 : 4,所以會有 :

k1 : k2 = 5 : 4  k2 : k3 = 5 : 4  k3 : k4 = 5 : 4

k1  k2  k3  k4 均是整數,所以不難找到最小的 k1 是 5×5×5,當然可以加任意倍數。那么的出來的桃子總數應該是 z = 5 x1+1 = 5 (5 k1 - 1) + 1 = 3125 k - 4 ,(k ∈ N)

解答

尼瑪,如果知道公式了 x = 3125 k - 4 ,答案不就是掏出來計算器然后計算一下的問題叻嚒 ! 前 10 個結果是 :

3121 6246 9371 12496 15621 18746 21871 24996 28121 31246

程序設計

程序猿的思路上面說了,從 1 開始試,直到滿足條件的結果出來。下面是計算最少的桃子數的程序 :

 1 int monkey(int n)
 2 {
 3     int res, left, count;    // 桃子總數 、 剩下的桃子數 、 可以分的猴子數
 4    
 5     left = res = 1;
 6     count = 0;
 7     while(1){
 8         if((left - 1) % 5 == 0){    // 可以再分一個猴子
 9             ++count;
10             left = (left - 1) / 5 * 4;
11         }else if(count != n){    // 不可以再分猴子了
12             left = ++res;
13             count = 0;
14         }
15         if(count == n)    // 滿足猴子總數, okay, 找到了
16             return res;
17     }
18 }

 

在上面程序的基礎上很容易修改,然后求出來多個結果來,下面給出一個簡單的擴展程序,max 用來限定桃子不超過的數目 :

 1 int monkey2(int n, int max, int *sum)
 2 {
 3     int res, left, count;    // 桃子總數 、 剩下的桃子數 、 可以分的猴子數
 4     int i = 0;    // 找到的解的個數
 5    
 6     left = res = 1;
 7     count = 0;
 8     while(1){
 9         if((left - 1) % 5 == 0){    // 可以再分一個猴子
10             ++count;
11             left = (left - 1) / 5 * 4;
12         }else if(count != n){    // 不可以再分猴子了
13             left = ++res;
14             count = 0;
15         }
16         if(count == n){    // 滿足猴子總數, okay, 找到了
17             sum[i++] = res;
18             left = ++res;
19             count = 0;
20         }
21         if(res > max)
22             return i;
23     }
24 }

ref


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM