蓝桥杯 入门训练 Fibonacci数列

蓝桥杯 入门训练 Fibonacci数列

后面说说自己的理解把。 
 
代码和问题描述都copy的。
 
问题描述

Fibonacci数列的递推公式为:Fn=Fn-1+Fn-2,其中F1=F2=1。

当n比较大时,Fn也非常大,现在我们想知道,Fn除以10007的余数是多少。

输入格式
输入包含一个整数n。
输出格式
输出一行,包含一个整数,表示Fn除以10007的余数。

说明:在本题中,答案是要求Fn除以10007的余数,因此我们只要能算出这个余数即可,而不需要先计算出Fn的准确值,再将计算的结果除以10007取余数,直接计算余数往往比先算出原数再取余简单。

样例输入
10
样例输出
55
样例输入
22
样例输出
7704
数据规模与约定
1 <= n <= 1,000,000。
 
 1 #include<stdio.h>
 2 #include<iostream>
 3 #include<stack>
 4 #include<vector>
 5 #include<queue>
 6 #include<deque>
 7 #include<string>
 8 
 9 using namespace std;
10 
11 
12 /* 入门训练 Fibonacci数列  */
13 #define N 10007
14 int main()
15 {
16     long int n = 0;
17     cin >> n;
18     int a, b,cur;
19     cur = a = b = 1;
20     for (n -= 2; n >0; n--)
21     {
22         cur = (a+b)%N;
23         a = b;
24         b = cur;
25     }
26     cout << b;
27 
28     return 0;
29 }

 

个人理解:

  对于“说明:在本题中,答案是要求Fn除以10007的余数,因此我们只要能算出这个余数即可,而不需要先计算出Fn的准确值,再将计算的结果除以10007取余数,直接计算余数往往比先算出原数再取余简单。”这种官方OJ已经给出的说明来看:

  1 我们应该是从这个余数方面的性质着手去找那个“不需要计算具体值而得出结果的方法”。

  2 这种题目里面,我们肯定是从利用余数方面区去思考。

  3 就两个数的合的余数,等于两个加数的余数的合再去 取余数。

  4 考虑 上面那点的问题,我们可以这样想:

    (1)余数这方面的数字问题,N(这题是10007)的整数倍的数值没关系。

    (2)这题一定只有余数起作用。

    (3)因为假设你正常算结果的话,到最终结果所有N的整数倍的数值都被减掉了。

    (4)如果余数相加之后超过了一倍的N的话,只要要去剪掉(取余)一倍的N就ok了。

    (5)综上,就有了 3 的结论。。

  5 所以我们在这道题中,只关心每个步骤的余数内容就够了。

  6 假如还在疑惑如果不是准确计算是不是还会影响结果的话我们还可以这么想:

    (1)将一个数字分成(N*x(x>=0)+ K(余数))

    (2)那么两个数字无论如果加减,都是N*x部分一定会被剪掉。

    (3)同时K部分的相加若超出了N,则x+1,K - N即可,即上面的 3 结论

 

 

以上。

转载于:https://www.cnblogs.com/THX-night/p/7994323.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值