蓝桥杯入门之斐波那契数列(Fibonacci)

斐波那契数列/百度介绍

斐波那契数列(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。那么最后就可以按着思路去解决问题了。

  • 7
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

搬砖的码蚁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值