斐波那契數列(二)

来源:https://www.cnblogs.com/cs-whut/archive/2022/12/16/16975148.html
-Advertisement-
Play Games

前言 明天就是擁抱情人節,情侶們會在公開的場合擁抱,向世人宣告你倆的愛意,也讓這個寒冷的冬天變得格外溫馨。到了年底依然能熱情擁抱,也見證了兩人情意如昔。 今天子川就給大家帶來就是的利用Python製作表白神器,記得發給自己的心儀對象。廢話不多說直接開整~ 開發工具 Python版本: 3.6 相關模 ...


        斐波那契數列在很多問題上得到了應用。下麵通過一些具體的實例加以說明。

【例1】鋼管切割

問題描述

給一根長度為n的鋼管,問最多能切割成幾段鋼管,使得截成的鋼管互不相等且均不能構成三角形。

輸入

輸入文件的第一行包含整數T(1≤T≤10) ,表示測試用例的數量。

每個測試用例包含一行,包括整數N(1≤N≤1018)表示鋼管的長度。

輸出

對於每個測試用例,輸出一行,一個整數表示它可以切割成的最大段數。

輸入樣例

1

6

輸出樣例

3

        (1)編程思路。

        本題是斐波那契數列的典型應用。

        下麵先以長度為150的鋼管切割為例進行說明。

        由於形成三角形的充要條件是任何兩邊之和大於第三邊,因此不構成三角形的條件就是存在兩邊之和不超過另一邊。而要將鋼管切割出的段數更多,則開始應儘可能切割出滿足要求的長度最短的鋼管,因此開始可以切割出一根長度為1和一根長度為2的兩根鋼管(切割出的鋼管長度互不相同),第3根鋼管的長度應該是3(為了使得切割的段數最大,因此要使剩下來的鋼管儘可能長,因此每一根鋼管總是前面的相鄰2根鋼管長度之和),之後依次為:1、2、3、5、8、13、21、34、55,以上各數之和為 142,與 150 相差 8,因此可以取最後一段鋼管長度為 63,這時段數達到最大為 9。

       在這個示例中,142是斐波那契數列的前項和,我們要把150超出142的部分加到最後的一個數上去,如果加到其他數上,就有3根鋼管可以構成三角形了。

        (2)源程式。

#include <stdio.h>
int main()
{
    long long f[110]={0,1,2},fsum[110]={0,1,3};
    int i;
    for (i=3; i<100; i++)
    {
        f[i] = f[i-1] + f[i-2];
        fsum[i] = fsum[i-1] + f[i];
    }
    int t;
    scanf("%d",&t);
    while (t--)
    {
        long long n;
        scanf("%lld",&n);
        for (i=1; i<100; i++)
        {
            if (fsum[i] == n)
            {
                break;
            }
            else if (fsum[i]>n)
            {
                i--;
                break;
            }
        }
        printf("%d\n",i);
    }
    return 0;
}

        將上面的源程式提交給HDU題庫 HDU 5620 KK's Steel  (http://acm.hdu.edu.cn/showproblem.php?pid=5620),可以Accepted。

【例2】三角形

問題描述

給定n根直棒,能否在這n根直棒中找出3根棒子組成一個三角形。

輸入

輸入有多個測試用例。

每個測試用例都以包含整數n的行開始(1≤n≤106),這表示直棒的數量,然後是n個正整數(小於231−1) 用空格隔開。

輸出

每個用例輸出YESNO表示可以或不能用三根直棒組成一個三角形。

輸入樣例

4

1 2 3 4

輸出樣例

YES

          (1)編程思路。

         由例1可知,三角形的三邊關係定理和斐波那契數列存在著一定的聯繫。由於斐波拉契數列級別增長很快,因此若n>=50,肯定可以找到3根直棒組成三角形。

         如果不能組成三角形,輸入數的個數 n< 50。將這n個數從小到大排序,排序後,再遍歷這n個數,若存在相鄰兩個數的和大於之後的1個數,即存在a[i-2]+a[i-1]>a[i],則這3根直棒可以組成三角形。

        (2)源程式。

#include <stdio.h>
int main()
{
    int n;
    while (scanf("%d",&n)!=EOF)
    {
        int i,j;
        int flag = 0;
        if (n < 50)
        {
            int a[50];
            for (i = 0; i < n; i++)
               scanf("%d", &a[i]);
            for (i=0;i<n-1;i++)
                for (j=0;j<n-1-i;j++)
                   if (a[j]>a[j+1])
                   {
                      int tmp;
                      tmp=a[j]; a[j]=a[j+1]; a[j+1]=tmp;
                   }
            for (i = 0; i < n - 2; i++)
               if (a[i]+a[i+1]>a[i+2]) { flag = 1; break; }
        }
        else
        {
            int x;
            for (i = 0; i < n; i++)
               scanf("%d", &x);
            flag = 1;
        }
        if (flag) printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}

      將上面的源程式提交給HDU題庫 HDU 6512 Triangle  (http://acm.hdu.edu.cn/showproblem.php?pid=6512),可以Accepted。

【例3】不包含相鄰1的序列

問題描述

給定正整數n,確定在長度為n的0、1序列中不包含相鄰1的序列的數量。例如,對於n=3,答案是5(序列000、001、010、100、101滿足要求,而011、110、111是不滿足要求的)。

輸入

第一行包含測試用例的數量。

對於每一個測試用例,在一行中單獨給定一個小於45的正整數。

輸出

每個測試用例的輸出都以包含“Scenario #i:”的行開始,其中i是從1開始的測試用例數。然後輸出一行,其中包含沒有相鄰1的n位序列個數。用空行終止方案的輸出。

輸入樣例

2

3

1

輸出樣例 

Scenario #1:

5

 

Scenario #2:

2

        (1)編程思路。

        設a[i]表示長度為i的0、1序列中不包含相鄰1的序列的數量,在長度為 i 的序列後面再加上1位可以構成長度為 i+1 的序列。若後面添加0,直接添加在長度為i的序列後面即可,有a[i]種序列;若後面添加1,則前面只能為0,即在長度為i-1的合法序列後面添加01,有a[i-1]種序列。 因此,a[i+1]=a[i]+a[i-1]。也就是斐波那契數列。

        (2)源程式。

#include <stdio.h>
int main()
{
    long long a[50];
    a[1] = 2;
    a[2] = 3;
    int i;
    for (i=3; i<=45; i++)
    {
        a[i]=a[i-1]+a[i-2];
    }
    int t,n;
    scanf("%d",&t);
    for (i=1;i<=t;i++)
    {
        scanf("%d",&n);
        printf("Scenario #%d:\n",i);
        printf("%lld\n\n",a[n]);
    }
    return 0;
}

      將上面的源程式提交給北大POJ 題庫POJ 1953 World Cup Noise (http://poj.org/problem?id=1953),可以Accepted。

【例4】合併相鄰的1        

問題描述

給定一個僅包含1的字元串;可以將兩個相鄰的1合併為2,或將1保留在那裡。這樣,可能會得到很多不同的結果。例如,給定1111,可以得到1111、121、112、211、22。現在,你的工作是找到你可以得到的結果總數。

輸入

第一行是數字n,表示測試用例的數量。接下來是n行,每行都有一個由1組成的字元串。序列的最大長度為200。

輸出

輸出包含n行,每行輸出可以獲得的結果數。

輸入樣例

3

1

11

11111

輸出樣例

1

2

8

        (1)編程思路。

      設a[i]表示由i個1組成的字元串可以獲得的結果數。當字元串長度增加到 i+1 時,最後一個1不參與合併,就單獨保留在那裡,可以得到的結果數為a[i];若最後1個1要參與合併,則只能與其前面的1個1合併,結果相當於在長度為i-1的字元串後面加了一個2,可以得到的結果數為a[i-1]。因此,a[i+1]=a[i]+a[i-1]。同樣也就是斐波那契數列。但由於題目給定的n最大為200。結果超過了長整數能表示的範圍,因此需要採用高精度計算。

        (2)源程式。

#include <stdio.h>
#include <string.h>
#define MOD 100000000
struct BigNumber
{
   int len;
   int num[205];
};
int main()
{
    struct BigNumber  f[205];
    memset(f[1].num,0,sizeof(f[1].num));
    memset(f[2].num,0,sizeof(f[2].num));
    f[1].len=f[2].len=1;
    f[1].num[0]=1;  f[2].num[0]=2;
    int i,j;
    for (i=3;i<=200;i++)
    {
        memset(f[i].num,0,sizeof(f[i].num));
        f[i].len = f[i-1].len;
        int cf=0;
        for (j=0;j<f[i].len;j++)
        {
           int num=f[i-1].num[j]+f[i-2].num[j]+cf;
           f[i].num[j]=num%MOD;
           cf=num/MOD;
        }
        if (cf!=0)  f[i].num[f[i].len++]=cf;
    }
    int t;
    scanf("%d",&t);
    while (t--)
    {
        char s[205];
        scanf("%s",s);
        int n=strlen(s);
        printf("%d",f[n].num[f[n].len-1]);
        for (i=f[n].len-2;i>=0;i--)
            printf("%08d",f[n].num[i]);
        printf("\n");
    }
    return 0;
}

        將上面的源程式提交給HDU題庫 HDU 1865 1sting (http://acm.hdu.edu.cn/showproblem.php?pid=1865),可以Accepted。

 【例5】最大和

問題描述

給定一個由n個正整數構成的序列A,每次從序列中選取兩個數相加後,將新數加入序列A中。問這樣操作k次後,序列A中所有數的和最大為多少?

輸入

輸入包括多個測試用例。每個測試用例第一行包含兩個整數n和k(2≤n≤100000,1≤k≤1000000000),第二行包含n個元素ai(1≤ai≤100000),表示序列A。

輸出

對於每個測試用例,輸出序列A的最大總和(mod 10000007)。

輸入樣例

3 2

3 6 2

輸出樣例

35

         (1)編程思路。

        要使序列中所有整數的和最大,每次操作時要選序列當前最大和次大的數相加,然後加入序列中。

        設序列當前最大數和次大數分別為a,b,則操作第1、2、3、4、5…次操作加入的數分別為a+b、2a+b、3a+2b、5a+3b、8a+5b…,可以推出第k次a和b的繫數為fib(k+1)、fib(k)。

        序列新添加的數之和為 a*(fib[2]+fib[3]+..fib[k+1]) + b*(fib[1]+fib[2]+..fib[k])。

        根據 (fib[1]+fib[2]+..fib[k]) = fib[k+2]-1,用矩陣快速算出fib[k+2]後計算即可。

        (2)源程式。 

#include <stdio.h>
#define MODNUM 10000007
struct Matrix {
      long long s11 , s12 , s21 , s22 ;
};
typedef struct Matrix matrix;
matrix f(matrix a,matrix b)
{
      matrix p ;
      p.s11 = (a.s11*b.s11 + a.s12*b.s21)%MODNUM;
      p.s12 = (a.s11*b.s12 + a.s12*b.s22)%MODNUM;
      p.s21 = (a.s21*b.s11 + a.s22*b.s21)%MODNUM;
      p.s22 = (a.s21*b.s12 + a.s22*b.s22)%MODNUM;
      return p ;
}
matrix quickpow(matrix p,long long n)    // 採用遞歸的方法實現矩陣快速冪運算
{
      matrix q ;
      q.s11 = q.s22 = 1 ;                                     // 初始化為單位矩陣
      q.s12 = q.s21 = 0 ;
      if (n == 0)
           return q ;
      q = quickpow(p,n/2);
      q = f(q,q);
      if (n%2)
           q = f(q,p);
      return q ;
}
int main()
{
      long long k ;
      int n,i;
      while (scanf("%d%lld",&n,&k)!=EOF)
      {
          long long ans=0,a=0,b=0,x,i;
          for (i=1;i<=n;i++)
          {
              scanf("%lld",&x);
              ans=(ans+x)%MODNUM;
              if (a<=x)
              {
                  b=a;  a=x;
              }
              else if (b<x)
                b=x;
          }
          matrix p ;
          p.s11 = p.s12 = p.s21 = 1 ;
          p.s22 = 0 ;
          p = quickpow(p,k+2);
          long long x1,x2,res;
          x1=p.s11-1;
          x2=p.s21-1;
          res=(x1*a)%MODNUM+(x2*b)%MODNUM;
          res=(res-a+MODNUM)%MODNUM;
          ans=(ans+res)%MODNUM;
          printf("%lld\n",ans);
      }
      return 0;
}

         將上面的源程式提交給HDU題庫 HDU 5171 GTY's birthday gift (http://acm.hdu.edu.cn/showproblem.php?pid=5171),可以Accepted。   


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 家居網購項目實現02 5.功能04-會員登錄 5.1需求分析/圖解 需求如圖: 輸入用戶名、密碼後提交 判斷該用戶是否存在 如果存在,顯示登錄成功頁面 否則返回登錄頁面,要求重新登錄 要求改進登錄密碼為md5加密 5.2思路分析 5.3代碼實現 根據上述分析圖,在對應的層添加方法 5.3.1dao層 ...
  • unique_ptr的成員函數在上一篇博客中幾乎全部涵蓋,其實還有一個很有踢掉,即std::unique_ptr::get_deleter字面已經很明顯了,就獲得deleter 智能指針採通過引用計數我們能解決多次釋放同一塊記憶體空間的問題,並且和之間直接移交管理權的方式比較這種方式更加靈活安全。 但 ...
  • 怎麼引入不同的庫? 線上安裝庫 1)pip install 模塊名 2)國內源: 清華:https://pypi.tuna.tsinghua.edu.cn/simple 阿裡雲:http://mirrors.aliyun.com/pypi/simple/ 中國科技大學 https://pypi.mi ...
  • 1.函數 #函數語法: #函數名規範:小謝字母開頭,不同字母下劃線隔開(字母數字下劃線) #def 函數名(): #函數體:希望函數做的事情 1.1.無參函數 #無參函數 def music(): print("唱著又沒動聽的歌聲...") #調用函數 music() 1.2.有參函數 #有參函數 ...
  • 1 鎖優化歷史 synchronized 從 JDK1.0到JDK1.5 ,效率低 JDK1.5到JDK1.6,JVM團隊對synchronized進行深度優化,加入了:適應性自旋、鎖消除、鎖膨脹、輕量級鎖、偏向鎖 等優化技術 JDK1.5 開始,加入java.util.concurrent,提供A ...
  • 小程式中實現頁面跳轉 對標簽綁定點擊事件 data是點擊時傳入的參數 <view bindtap="clickMe" data-nid="123" data-name="SD" >點我跳轉</view> /** * 用戶點擊事件 */ clickMe(e){ console.log(e) var n ...
  • 我要說的是我們改變 num屬性 的類型,無論是由 Integer改成Long,還是由Long改成Integer,只要num的值在Integer取值範圍內,就不會影響hessian序列化。 ...
  • 股票分析 需求:股票分析 使用tushare包獲取某股票的歷史行情數據。 輸出該股票所有收盤比開盤上漲3%以上的日期。 輸出該股票所有開盤比前日收盤跌幅超過2%的日期。 假如我從2010年1月1日開始,每月第一個交易日買入1手股票,每年最後一個交易日賣出所有股票,到今天為止,我的收益如何? impo ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...