問題描述:
a,b,c,d,e這5個人合夥夜間捕魚,凌晨時都已經疲憊不堪,於是各自在河邊的樹叢中找地方睡著了。第二天日上三竿時,a,第乙個醒來,他將魚平分為5份,把多餘的一條扔回河中,然後拿著自己的乙份回家去了;b第二個醒來,但不知道a已經拿走了乙份魚,於是他將剩下的魚平分為5份,扔掉多餘的乙份,然後只拿走了自己的乙份;接著c,d,e一次醒來,也都按照同樣的辦法分魚。問5人至少合夥捕到多少條魚?每個人醒來後所看到的魚是多少條?
問題分析:
假設5個人合夥捕了x條魚,則「a第乙個醒來,他將魚平分為5份,把多餘的一條扔回河裡,然後拿著自己的乙份回家去了」之後,還剩下4(x-1)/5條魚,這裡實際包含了乙個隱含條件:假設xn為第n(n=1,2,3,4,5)個人分魚前魚的總數,則(xn-1)/5必須為正整數,否則不合題意。(xn-1)/5為正整數即(x~1)mod5 = 0必須成立。
又根據題意,應該有下面等式:
x4 = 4(x5-1)/5
x3 = 4(x4-1)/5
x2 = 4(x3-1)/5
x1 = 4(x2-1)/5
則一旦給定x5,就可以推算x4,x3,x2和x1的值。要保證x5,x4,x3,x2和x1都滿足條件(xn-1)mod5 = 0,此時x5則為5個人合夥補到的魚的總條數。顯然,5個人合夥可能捕到的魚的條數並不唯一;但題目中強調了「至少」合夥捕到的魚。此時題目的答案唯一。該問題可使用遞迴的方法求解。
程式設計:
在main()函式中構建呢乙個不定次數的do-while迴圈。定義變數x表示5個人合夥可能捕到的魚的條數,可以取到x的最小值為6,讓x值逐漸增加,x每一次取值,都增加5,知道找到乙個符合問題要求的答案。由於題目中問「5人至少合夥捕到多少條魚」,而我找到的第乙個x值就是5個人至少捕到的魚的總條數。
通過這個迴圈,就可以對每乙個的可能情況進行檢查。當然,是通過呼叫分魚的遞迴函式進行檢查的
分魚的遞迴函式如下:
fish()函式中包含了兩個引數:n和x。n表示參與分魚的人數,x表示n個人分魚前魚的總條數。這兩個引數都是由main()函式中傳遞進來的。
根據前面的分析,當n=5時,(n-1)mod5==0 必須成立,否則該x值不是滿足題意的值,退出fish函式,返回到main()函式,main()函式中再傳遞新的x值到fish中進行檢驗。如果(x-1)mod5==0 條件成立,則要判斷n=4時,(x-1)mod5==0 條件是否成立,需要注意的是,此時的行參x是4個人分魚前魚的總條數,即f(5,x)遞迴呼叫f(4,(x-1)/5*4)。這樣依次進行下去,直到n=1時,(x-1)mod5==0條件仍成立,則說明開始從main()函式中傳遞進去的x值是符合題意要求的乙個值,可以逐層從遞迴函式中返回,每次返回值都為1,直到返回到main() 函式。
下面是完整的**:
#include
/*分魚遞迴函式*/
int fish(int n,int x)
if((x-1)%5 == 0)
if(n == 1)
return 1; /*遞迴出口*/
else
return fish(n-1,(x-1)/5*4); /*遞迴呼叫*/
return 0; /*x不是符合題意的解,返回0*/
int main()
int i = 0;flag = 0,x;
doi = i + 1;
x = i*5+1;/*x最小值為6,以後每次增加5*/
if(fish(5,x))/*將x傳入分魚遞迴函式進行檢驗*/
flag = 1;/*找到第乙個符合題意的x則置標誌位為1*/
printf("五個人合夥捕到的魚總數字%d\n",x);
}while(!flag)/*未找到符合題意的x,繼續迴圈,否則退出迴圈*/
return 0;
執行結果:
五個人合夥捕到的魚總數為3121
知識點補充:
本題還可以使用「遞推法」來求解。下面先對遞推法做下簡介。
遞推法:利用問題本身所具有的遞推關係來求解。所謂的遞推關係指的是:當得到問題規模為n-1的解後,可以得出問題規模為n的解。因此,從規模為0或1的解可以一次遞推出任意規模的解。
下面是完整的**:
#include
/*分魚遞迴函式*/
int fish(int n,int x)
if((x-1)%5 == 0)
if(n == 1)
return 1; /*遞迴出口*/
else
return fish(n-1,(x-1)/5*4); /*遞迴呼叫*/
return 0; /*x不是符合題意的解,返回0*/
int main()
int fish[6],i;
fish[5] = 6;
while(1)
for(i =4;i>0;i--)
if(fish[i+1]%4 != 0)
break;
fish[i] = fish[i+1]*5/4 + 1;
if(fish[i]%5 = 1)
break;
if(i == 0)
break;
fish[5]+=5;
for(i=1;i<=5;i++)
printf("fish[%d] = %d\n",i,fish[i]);
return 0;
運訓結果:
fish[1] = 3121
fish[2] = 2496
fish[3] = 1996
fish[4] = 1596
fish[5] = 1276
C語言 遞迴解決分魚問題。
a b c d e五個人在某天夜裡合夥去捕魚,到凌晨時疲憊不堪,於是各自找地方睡覺。第二天a醒來,他將所有的魚分成5份,把多餘的一條魚扔掉,拿走自己的乙份。b醒來,也將剩下的魚分為5份,把多餘的一條扔掉,拿走自己的乙份。c d e 也同樣,分別醒來後,也將剩下的魚分為5份,把多餘的一條扔掉,拿走自己...
1 遞迴解決分魚問題
問題描述 a b c d e這5個人合夥夜間捕魚,凌晨時都已經疲憊不堪,於是各自在河邊的樹叢中找地方睡著了。第二天日上三竿時,a第乙個醒來,他將魚平分為5份,把多餘的一條扔回河中,然後拿著自己的乙份回家去了 b第二個醒來,但不知道a已經拿走了乙份魚,於是他將剩下的魚平分為5份,扔掉多餘的一條,然後只...
遞迴 解決ABCDE 5人分魚問題魚,
題目 有abcde五人夜間到河邊捕魚,捕完魚後五人在河邊睡著.天亮後a先醒來,將所捕魚平均分偉五份,結果餘一條,將餘的一條扔掉,帶走自己的一堆.b醒來將餘下的四堆又分為五份,也餘一條,同樣仍掉,也帶走自己的一堆.c d e醒來後也如此,問他們這天晚上至少捕到多少條魚?廢話不多說,分析 首先我寫了這樣...