遞迴解決分魚問題 c語言

2021-09-29 06:25:06 字數 2806 閱讀 6585

問題描述:

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醒來後也如此,問他們這天晚上至少捕到多少條魚?廢話不多說,分析 首先我寫了這樣...