斐波那契数列/百度介绍
斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,斐波那契数列以如下被以递推的方法定义:F(1)=1,F(2)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 3,n ∈ N*)在现代物理、准晶体结构、化学等领域,斐波纳契数列都有直接的应用,为此,美国数学会从 1963 年起出版了以《斐波纳契数列季刊》为名的一份数学杂志,用于专门刊载这方面的研究成果。
蓝桥杯入门之斐波那契数列(Fibonacci)
问题描述:
Fibonacci数列的递推公式为:Fn=Fn-1+Fn-2,其中F1=F2=1。
当n比较大时,Fn也非常大,现在我们想知道,Fn除以10007的余数是多少
解题思路:
学过算法的同学,应该都知道,解决斐波那契数列问题的方法有两种,一种是递归式,一种是非递归式。在这里,递归式不适合使用,因为题目说了n比较大,Fn也比较大,假如使用递归式,会大量消耗栈内存,甚至导致栈溢出问题。在这里采用的是非递归式,代码实现如下:
#include<iostream>
using namespace std;
int fib(int N) {
if (N <= 0) return 0; //判断n是否小于等于零
if (N == 1 || N == 2) return 1;//假如数列只有一项或者两项的时候,函数返回值应该为1
int a = 1, b = 1; //当n>2时,变量a保存的是F(n-2)项的值,变量b保存的是F(n-1)的值
for (int i = 3; i <= N; i++) //循环计算第n项的值
{
int c = (a + b) % 10007; //见下面详细解释
a = b;
b = c;
}
return b;
}
int main()
{
int n;
cin >> n;
//cout << fibonacci(10) << endl;
cout << fib(n) << endl;
//cout << fibonacci(10007) << endl;
while (1);
return 0;
}
int c= (a + b)%10007的详细解释:
假设题目要求只需要求出第n项值,就不需要%10007,即写成int c=a+b即可,就是正式的斐波那契数列的非递归式。但是,因为题目n很大,所以正式的斐波那契数列求第n项值会发生溢出问题,即第n项值大于INT_MAX(int类型的最大值)。所以呢,不能用正式的非递归式求出第n项值后,再取第n项值的模。要求出第n项取10007的模的值,必须在循环中对每一项取模。小于10007的值取模后,结果是它原来值,比如10%10007=10;大于10007的值取模后,结果是原来值取模后的余数,比如100010%10007=3。每次循环都会记录取余数的结果到a,b变量中。
如此,斐波那契数列问题就转变成,第n项取余数的值=(第n-2项的值+第n-1项的值)%10007,F(n)余数=(F(n-2)+F(n-1))%10007。那么最后就可以按着思路去解决问题了。