Fibonacci大数和(仅打印最后一位数字)

时间:2016-08-15 06:56:27

标签: c++ c performance fibonacci

我一直试图找出解决大型n斐波那契数列之和的最后一位数的问题的解决方案。 我已经能够通过几个大n的测试用例。但是我坚持下面的情况,其中n = 832564823476。我知道它可以用Pisano的时期来解决,但我无法提出一个有效的算法。任何帮助都会很棒。谢谢。 我实现的代码如下 -

#include <iostream>
using namespace std;


int calc_fib(int n) {

    int fib[n+1];
    fib[0]=0;
    fib[1]=1;
    int res = 1;
    for(int i = 2; i<=n;i++){
        fib[i] = (fib[i-1]%10 + fib[i-2]%10)%10;
        res = res + fib[i];
    }
    return (res%10);
}

int main() {
    int n = 0;
    std::cin >> n;

    std::cout << calc_fib(n) << '\n';
    return 0;
}

6 个答案:

答案 0 :(得分:9)

已解决此问题

适用于所有输入范围。它适用于以下算法。 我们的想法是注意到斐波那契数的最后数字也出现在长度为60的序列中(来自前一个问题:因为10的pisano peiod是60)。无论n多大,它的最后一个数字都会出现在序列中的某个位置。 除了最后一位数的10个边缘情况之外的两件事。

  • 第n个Fibonacci系列的和= F(n + 2)-1
  • 然后模块10的pisano周期=让n + 2 mod(60)= m然后找到F(m)mod(10)-1

代码如下;

#include <iostream>
using namespace std;

long long calc_fib(long long n) {

    n = (n+2)%60;
    int fib[n+1];
    fib[0]=0;
    fib[1]=1;
    int res = 1;
    for(int i = 2; i<=n;i++){
        fib[i] = (fib[i-1]%10 + fib[i-2]%10)%10;
        // res = res + fib[i];
    }
    // cout<<fib[n]<<"\n";
    if(fib[n] == 0){
        return 9;
    }
    return (fib[n]%10-1);
}

int main() {
    long long n = 0;
    std::cin >> n;

    std::cout << calc_fib(n) << '\n';
    return 0;
}

答案 1 :(得分:1)

如果您只需按照说明输出最后一位数字,我认为您可以使用您提到的Pisano Period,对于模块化10,周期长度仅为60,您可以预先制作一个60位数的数组。

如果你想自己计算,我认为你可以使用Matrix Exponentiation给你O(lg N)复杂度,在计算矩阵指数时,继续存储临时结果模块10.参见{{3部分供您参考。

答案 2 :(得分:1)

斐波纳契和的最后一位数字在60个元素后重复。

此处的周期为60 [0-59]。 因此,要得到第n个数字之和的最后一位是n%第60个数字之和的最后一位 数字

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
$("p").show(
<button id="correct">duration, easing</button>
<button id="error">easing, duration -> ERROR</button>
)
<p style="display: none">Hello</p>

答案 3 :(得分:0)

用于删除阵列的功能。

#include "stdafx.h"
#include <iostream>
using namespace std;
int calc_fib(long long int n) {

    int fibzero = 0;
    int fibone = 1;
    int fibnext;
    long long int res = 1;
    for (long long int i = 2; i <= n; i++) {

        fibnext = (fibone + fibzero) % 10;
        fibzero = fibone;
        fibone = fibnext;
        res = res + fibnext;
    }
    return (res % 10);
}

int main() 
{
    long long int n = 0;
    std::cin >> n;

    std::cout << calc_fib(n) << '\n';
    return 0;
}

答案 4 :(得分:0)

实际上它比Niall回答更容易

int get_fibonacci_sum_last_digit(long long n) {
    const int kPisanoSize = 60;
    int rest = n % kPisanoSize;
    int preparedNumbers[kPisanoSize] = {0, 1, 2, 4, 7, 2, 0, 3, 4, 8, 3, 
        2, 6, 9, 6, 6, 3, 0, 4, 5, 0, 6, 7, 4, 2, 7, 0, 8, 9, 8, 8, 7, 
        6, 4, 1, 6, 8, 5, 4, 0, 5, 6, 2, 9, 2, 2, 5, 8, 4, 3, 8, 2, 1, 
        4, 6, 1, 8, 0, 9, 0};
    return preparedNumbers[rest];

}

答案 5 :(得分:0)

解决问题的巧妙方法(我使用java)。逻辑是利用10的pisano周期。写下Sum(F(n)) = F(n+2) + 1之间的对应关系会很有帮助。提示:单独创建一个斐波那契数列。

const SectionTitle = ({ step }) => {
  console.log('step', step);

  return (
    <div className="sectionWrapper">
      <div className="titleWrapper">
        <div className="title">Title</div>
        <div className="nextStep">
           SubTitle
        </div>
      </div>
      <ProgressBar styles={{ height: 50 }} />
    </div>
  );
};
export default SectionTitle;