斐波那契数列初级版
從今天開始,我會(huì)介紹一些關(guān)于斐波那契數(shù)列在ACM競賽中的典型題目,以便廣大的ACMer能從中受益,能更好地
掌握它。
?
?
題目:http://acm.nefu.edu.cn/JudgeOnline/problemShow.php?problem_id=462
?
題意:已知是斐波那契數(shù)列,求如下表達(dá)式的值。
?
?????
?
分析:我們知道斐波那契數(shù)列的公式是
?
????
?
?????那么得到
?
????
?
???? 進(jìn)一步有
?
????
?
???? 通過二項(xiàng)式定理,知道
?
????
?
???? 那么最終得到
?
????
?
?
題目:http://acm.hdu.edu.cn/showproblem.php?pid=1568
?
分析:題意是求斐波那契數(shù)列的前4位。根據(jù)斐波那契數(shù)列的公式,可以得到
?
????
?
?????很明顯,當(dāng)足夠大時(shí),得到
?
?????
?
代碼:
#include <iostream> #include <stdio.h> #include <math.h>using namespace std;const int N = 25; int fac[N] = {0, 1, 1};int main() {int n;for(int i=3; i<22; i++)fac[i] = fac[i-1] + fac[i-2];while(cin>>n){if(n <= 20){cout<<fac[n]<<endl;continue;}double bit = -0.5 * log10(5.0) + n * log10((sqrt(5.0) + 1) / 2.0);bit = bit - floor(bit);bit = pow(10.0, bit);while(bit < 1000) bit *= 10.0;printf("%d\n", (int)bit);}return 0; }
?
題目:http://acm.nefu.edu.cn/JudgeOnline/problemshow.php?problem_id=461
?
題意:廣義斐波那契數(shù)列的定義如下
?
????
?
???? 這里是實(shí)數(shù),是正整數(shù),給定,求的位數(shù)。
?
分析:廣義斐波那契數(shù)列是可以推出公式的,接下來,我將會(huì)詳細(xì)寫出公式的推導(dǎo)過程
?
???? 根據(jù),知道對應(yīng)的特征方程為,解之得
?
?????
?
???? 然后可以寫出
?
????
?
???? 兩式聯(lián)立消去,得到
?
?????
?
???? 再進(jìn)一步得到
?
?????
?
?????針對本題來說,在大于200的情況下
?
????
?
???? 近似為零,所以最終得到
?
????
?
???? 接下來就可以根據(jù)上述方程求的位數(shù)了。
?
代碼:
#include <iostream> #include <string.h> #include <stdio.h> #include <math.h>using namespace std; typedef long long LL;int main() {LL n, a, b, u, v;while(cin>>n>>a>>b>>u>>v){double t = sqrt(u * u + 4 * v);double p = (u + t) / 2.0;double q = (u - t) / 2.0;double ans = n * log10(p) + log10(b - q * a) - log10(t);cout<<(LL)ans + 1<<endl;}return 0; }
?
題目:http://acm.hdu.edu.cn/showproblem.php?pid=2814
?
題意:已知是斐波那契數(shù)列,給定,求的值,其中。
?
分析:本題由于比較小,可以直接暴力找循環(huán)節(jié),然后再通過指數(shù)循環(huán)節(jié)進(jìn)行降冪即可。
?
代碼:
#include <iostream> #include <string.h> #include <stdio.h>using namespace std; typedef unsigned long long LL;LL f[5500];int search(int c) {f[0] = 0;f[1] = 1;int loop = 0;for(int i = 2; i < 2005; i++){f[i] = (f[i-1] + f[i-2]) % c;if(f[i] == 1 && f[i-1] == 0){loop = i;break;}}return loop - 1; }int phi(int n) {int rea = n;for(int i = 2; i * i <= n; i++){if(n % i == 0){rea = rea - rea / i;while(n % i == 0) n /= i;}}if(n > 1)rea = rea - rea / n;return rea; }LL multi(LL a, LL b, LL m) {LL ans = 0;while(b){if(b & 1){ans = (ans + a) % m;b--;}b >>= 1;a = (a + a) % m;}return ans; }LL quick_mod(LL a, LL b, LL m) {LL ans = 1;a %= m;while(b){if(b & 1){ans = multi(ans, a, m);b--;}b >>= 1;a = multi(a, a, m);}return ans; }int main() {int T;scanf("%d", &T);for(int i = 1; i <= T; i++){int c;LL a, b, n;scanf("%I64u %I64u %I64u %d", &a, &b, &n, &c);printf("Case %d: ",i);if(c == 1){puts("0");continue;}int p = phi(c);int loop1 = search(c);LL t1 = quick_mod(a, b, loop1);LL tmp1 = f[t1] % c;int loop2 = search(p);LL t2 = quick_mod(a, b, loop2);LL tmp2 = f[t2] % p;tmp2 = quick_mod(tmp2, n - 1, p);tmp2 += p;tmp1 = quick_mod(tmp1, tmp2, c);printf("%I64u\n", tmp1);}return 0; }
?
題目:http://acm.hdu.edu.cn/showproblem.php?pid=3936
?
題意:已知是斐波那契數(shù)列,,給定,求下面表達(dá)式的值
?
????
?
分析:首先我們要認(rèn)識(shí)兩個(gè)重要的性質(zhì)
?
????
?
???? 推導(dǎo)過程如下
?
???? 因?yàn)?#xff0c;那么,依次累加得到
?
????
?
????
?
???? 根據(jù)上述的兩個(gè)性質(zhì),可以得到
?
?????
?
???? 那么最終得到
?
????
?
???? 到了這里,剩下的僅僅是矩陣快速冪而已。
?
?
題目:http://acm.hdu.edu.cn/showproblem.php?pid=1316
?
題意:給定兩個(gè)數(shù)和,其中,求在區(qū)間內(nèi)有多少個(gè)斐波數(shù)。
?
分析:先預(yù)處理出一定范圍內(nèi)的斐波數(shù),然后再做兩次比較就可以了。比較簡單,代碼省略。
?
?
題目:http://codeforces.com/contest/318/problem/C
?
題意:給定一對,每次可以用去替換或,使得最后和中至少有一個(gè)大于等于,求最少的替換
???? 操作數(shù)。
?
分析:模擬一下,每次用去替換和中最小的那個(gè),會(huì)看出與斐波那契數(shù)列有關(guān)。
?
代碼:
#include <iostream> #include <string.h> #include <stdio.h>using namespace std; typedef long long LL; const int N = 95;LL dp[N];void Init() {dp[0] = 0;dp[1] = 1;for(int i = 2; i < N; i++)dp[i] = dp[i - 1] + dp[i - 2]; }LL Find(LL x, LL y, LL m, LL t) {LL ans = 0;for(int i = 0; i < N - 1; i++){if(x * dp[i] + y * dp[i + 1] >= m){ans = i;break;}}ans += t;return ans; }int main() {Init();LL x, y, m;while(cin>>x>>y>>m){if(x > y) swap(x, y);if(x >= m || y >= m){puts("0");continue;}if(x <= 0 && y <= 0){if(y >= m) puts("0");else puts("-1");continue;}LL t = 0;if(x < 0){t = -x / y + 1;x += t * y;}LL ans = Find(x, y, m, t);cout<<ans<<endl;}return 0; }
?
?
?
總結(jié)
- 上一篇: 第一类Stirling数和第二类Stir
- 下一篇: 连分数求解Pell方程