斐波那契數列的應用_斐波那契鳳尾、養兔子、客似雲來

1.斐波那契鳳尾

鏈接:https://www.nowcoder.com/questionTerminal/c0a4b917a15f40a49ca10532ab9019fb
來源:牛客網

題目描述:
NowCoder號稱自己已經記住了1-100000之間所有的斐波那契數。
爲了考驗他,我們隨便出一個數n,讓他說出第n個斐波那契數。當然,斐波那契數會大。
因此,如果第n個斐波那契數不到6位,則說出該數;否則只說出最後6位。

輸入描述:
輸入有多組數據。
每組數據一行,包含一個整數n (1≤n≤100000)。

輸出描述:
對應每一組輸入,輸出第n個斐波那契數的最後6位。

示例:

輸入
1
2
3
4
100000

輸出
1
2
3
5
537501

題目分析:

  1. 斐波那契數增長速度很快,當超過25項時,斐波那契數超過六位數。
  2. 輸入數據 n 的範圍是 1≤n≤100000,所以隨着n的增大,很難計算或保存斐波那契數。
  3. 在這裏計算的時候,只保留每個斐波那契數的後六位,這樣用 int 類型就可以保存前1000000項斐波那契數,具體操作是與1000000進行求餘運算。
  4. 斐波那契數是由前兩項的和計算得出,因此,計算前兩項後六位的和再也可以保證結果是該項斐波那契數的後六位。
  5. 輸出時,原本斐波那契數超過六位,但求餘運算後不滿六位,輸出時可以在前面補0。

代碼示例:

#include <iostream>
#include <vector>
#include <iomanip>
using namespace std;

int main()
{
    vector<int> v(1000002);
    v[0]=1;
    v[1]=1;
    for(int i=2;i<=1000000;++i)
    {
        v[i]=v[i-1]+v[i-2];
        v[i]%=1000000;
    }
    int n;
    while(cin>>n)
    {
        if(n>=25)
        {
            cout<<setfill('0')<<setw(6)<<v[n]<<endl;
        }
        else
            cout<<v[n]<<endl;
    }
    return 0;
}

2.養兔子

鏈接:https://www.nowcoder.com/questionTerminal/71d3849a19f04a1591c415964ac148f1?toCommentId=51150
來源:牛客網

題目描述:
一隻成熟的兔子每天能產下一胎兔子。每隻小兔子的成熟期是一天。 某人領養了一隻小兔子,請問第N天以後,他將會得到多少隻兔子。

輸入描述:
測試數據包括多組,每組一行,爲整數n(1≤n≤90)。

輸出描述:
對應輸出第n天有幾隻兔子(假設沒有兔子死亡現象)。

示例
輸入
1
2

輸出
1
2

題目分析:

  1. 通過列舉前幾項,可以看到此題是明顯的斐波那契數列應用問題,題目要求輸出指定項的斐波那契數。
  2. 給定輸入範圍是 n(1≤n≤90),所以在計算過程中要防止數據溢出。

代碼示例:

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    vector<int64_t> v(91);
    v[0]=1;
    v[1]=1;
    for(int i=2;i<91;++i)
    {
        v[i]=v[i-1]+v[i-2];
    }
    int n=0;
    while(cin>>n)
    {
        cout<<v[n]<<endl;
    }
    return 0;
}

3.客似雲來

鏈接:https://www.nowcoder.com/questionTerminal/3549ff22ae2c4da4890e9ad0ccb6150d
來源:牛客網

題目描述:

NowCoder開了一家早餐店,這家店的客人都有個奇怪的癖好:他們只要來這家店喫過一次早餐,就會每天都過來;並且,所有人在這家店吃了兩天早餐後,接下來每天都會帶一位新朋友一起來品嚐。於是,這家店的客人從最初一個人發展成浩浩蕩蕩成百上千人:1、1、2、3、5……現在,NowCoder想請你幫忙統計一下,某一段時間範圍那他總共賣出多少份早餐(假設每位客人只吃一份早餐)。

輸入描述:

測試數據包括多組。
每組數據包含兩個整數from和to(1≤from≤to≤80),分別代表開店的第from天和第to天。

輸出描述:

對應每一組輸入,輸出從from到to這些天裏(包含from和to兩天),需要做多少份早餐。

題目分析:

  1. 通過列舉前幾項,可以看到此題是明顯的斐波那契數列應用問題,題目要求對斐波那契數列指定區間項求和。
  2. 給定輸入範圍是 1≤from≤to≤80,所以在計算過程中要選擇合適的數據類型,防止數據溢出。
  3. 波那契數列的的前n項和是有一個很有意思的公式,這裏只用結果。
  4. 斐波那契數列的前n項和,就是第n+2項的值減1。所以,要求第n項到第m項的和,那麼只要求出前m項的和,減去前n - 1項的和,就能得到結果。例如要求第3項到第5項的和,我們就只需要用前5項的和減去前2項的和,而公式中的減一在這個過程中抵消掉了,也就是結果直接就是第7項的值減去第4項的值,這樣我們在操作的時候就更簡單了。就數值而言,第7項是13,第4項是3,差值是10,而2+3+5也是10,結果是正確的。

代碼示例:

循環求和:

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    vector<uint64_t> v(80);
    v[0]=1;
    v[1]=1;
    for(int i=2;i<80;++i)
    {
        v[i]=v[i-1]+v[i-2];
    }
    int from,to;
    while(cin>>from>>to)
    {
        uint64_t sum=0;
        for(int i=from;i<=to;++i)
        {
            sum+=v[i-1];
        }
        cout<<sum<<endl;
    }
    return 0;
}

用前n項和公式求和

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    vector<uint64_t> v(82);
    v[0]=1;
    v[1]=1;
    for(int i=2;i<82;++i)
    {
        v[i]=v[i-1]+v[i-2];
    }
    int from,to;
    while(cin>>from>>to)
    {
        uint64_t sum=0;
        sum=v[to+1]-v[from];
        cout<<sum<<endl;
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章