PAT乙級(Basic Level)練習題-NowCoder數列總結

來源:互聯網
上載者:User

標籤:block   [1]   names   左移   max   練習題   cci   std   運算   

題目描述

NowCoder最近在研究一個數列:

  • F(0) = 7
  • F(1) = 11
  • F(n) = F(n-1) + F(n-2) (n≥2)
    他稱之為NowCoder數列。請你幫忙確認一下數列中第n個數是否是3的倍數。
輸入描述:

輸入包含多組資料。
每組資料包含一個整數n,(0≤n≤1000000)。

輸出描述

對應每一組輸入有一行輸出。
如果F(n)是3的倍數,則輸出“Yes”;否則輸出“No”。
---

輸入例子:

0
1
2
3
4
5

輸出例子:

No
No
Yes
No
No
No
---

題目分析

這是一個特殊初始條件的Fibonacci sequence.

1.初始條件n的值比較小,可以直接枚舉每個F(n)的值,然後輸入n查詢:
#include <iostream>  #include <cstdio>  using namespace std;  int main (){      int n;      int *a=new int[N];    a[0]=7;    a[1]=11;    for(int i=2;i<N;i++)        a[i]=a[i-2]%3+a[i-1]%3;    while(~scanf("%d", &n)){        cout<<a[n]<<endl;        if(a[n]%3==0)            cout<<"Yes"<<endl;        else            cout<<"No"<<endl;       }    return 0;  }  
2.可以尋找到規律:(牛客網友“我要過pat”提供)

這個真牛批,想不到還有這種規律。那Fibonacci數列是否有相似的規律呢?

#include <iostream>  using namespace std;int main (){      int n;      while(cin>>n){    if((n-2)%4==0)        cout<<"Yes"<<endl;    else         cout<<"No"<<endl;    }    return 0;  }  
3.用矩陣快速冪來求解,這題n的範圍比較小(0≤n≤1000000)所以用第1種方法可以不逾時求解,但是,倘若n很大,達到(1<=n<=1000,000,000,000,000,000)這個範圍,那麼顯而易見,必定逾時。而且根本開不到那麼大的數組。學校的演算法課,有另外一題類似的,可以思考一下:

藉此思路,用矩陣快速冪計算,稍微修改下就可以了。

 #include <iostream>  #include <cstdio>  #include <cstring>  #define N 3#define maxn 2       using namespace std;    struct Matrix{      long long a[maxn][maxn];      void init(){    //初始化為單位矩陣           memset(a, 0, sizeof(a));          for(int i=0;i<maxn;++i){              a[i][i] = 1;          }      }  };    //矩陣乘法   Matrix mul(Matrix a, Matrix b){      Matrix ans;      for(int i=0;i<maxn;++i){          for(int j=0;j<maxn;++j){              ans.a[i][j] = 0;              for(int k=0;k<maxn;++k){                  ans.a[i][j] += a.a[i][k] * b.a[k][j];                  ans.a[i][j] %= N;               }          }      }       return ans;  }    //矩陣快速冪   Matrix qpow(Matrix a, long long n){      Matrix ans;      ans.init();      while(n){          if(n&1)               ans = mul(ans, a);          a = mul(a, a);          n /= 2;      }       return ans;  }    int main (){      long long n;        while(~scanf("%lld", &n)){    Matrix a;      a.a[0][0] = 1;      a.a[0][1] = 1;      a.a[1][0] = 1;      a.a[1][1] = 0;      long long s0=7,s1=11;       if (n>1)          {          Matrix ans= qpow(a, n-1);          long long res=ans.a[0][0]*s1+ans.a[0][1]*s0;  //        printf("%lld",res);         if(res%3==0)            cout<<"Yes"<<endl;        else            cout<<"No"<<endl;           }                 else          cout<<"No"<<endl;                       }    return 0;  }  

測評網站真的噁心,有時候迴圈輸入用"cin>>"就可以,有時候又逾時。。。得改"成~scanf("%lld", &n)"。另外一開始沒想到對中間結果對3模數,導致數值過大溢出。用到unsigned long long 都不夠。。。

PS:檢測一個數被3整除的演算法

1.檢測一個數能否被3整除----位元運算

如果所有的偶數位出現1的次數為 even_count, 奇數位出現1的次數為 odd_count,兩者只差如果是3的倍數,那麼這個數就是3倍數。

2.不用除法和求模運算,判斷一個數能否被3整除

現在給出一個數a,假設它能被3整除,結果是b,即a=3*b,那麼從二進位乘法運算判斷出,b的最低位與a的最低位一定是相同的,從而得到了b的最低位,將這個位左移1位變成次低位,那麼a的次低位以上的位元減去這個位後在次低位上的結果一定是b的次低位。以此類推可以求出b的各個位元,如果最後能完成對b的各位的計算,那麼a能夠被3整除,否則不能被3整除。

那麼演算法原理是什麼呢?

PAT乙級(Basic Level)練習題-NowCoder數列總結

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.