【问题标题】:Last Digit of the Sum of Fibonacci Numbers斐波那契数之和的最后一位
【发布时间】:2019-05-29 05:14:41
【问题描述】:

我试图找到斐波那契数列总和的最后一位。我将总和计算为F(n+2) - 1。下面的代码工作正常,但对于大数字(例如99999)来说速度很慢。 我该如何优化它?

n = int(input())

def last_digit(n):
    a, b = 0, 1
    for i in range(n+2):
        a, b = b, a + b
    return (a-1) % 10

print(last_digit(n))

【问题讨论】:

  • 斐波那契数列增长得非常快(指数),这导致 Python 求助于任意精度类型。您将需要模数数学规则以将数字保持在 32/64 位整数范围内。
  • 有一种方法...在下面查看我的答案。

标签: python python-3.x fibonacci largenumber


【解决方案1】:

看这张表:http://www.maths.surrey.ac.uk/hosted-sites/R.Knott/Fibonacci/fibtable.html 注意fib(60)最后一位是0fib(61)最后一位是1,和fib(0)fib(1)一样,因此从60开始最后一位开始重复,所以你可以计算fib(n%60) 的最后一位数字,而不是 fib(n)。 例如,fib(115)fib(55) 的最后一位数字相同,等于 5

【讨论】:

    【解决方案2】:

    斐波那契数repeats的末位序列,周期为60。因此,可以将n项和的计算优化为F((n+2) % 60) - 1。此外,要保持在整数范围内,您可以只保留每个术语的最后一位:

    def last_digit(n):
        a, b = 0, 1
        for i in range((n + 2) % 60):
            a, b = b, (a + b) % 10
        return 9 if a == 0 else a - 1
    
    print([last_digit(n) for n in range(1, 11)])
    

    输出:

    [1, 2, 4, 7, 2, 0, 3, 4, 8, 3]
    

    【讨论】:

      【解决方案3】:

      这是专门针对最后一位数字优化的代码:

      def fib(n):
          a, b = 0, 1
          r = 1
          if n < 1:
              return 0
          for i in range(n - 1):
              a, b = b, (a + b)%10
              r += b
              r %= 10
          return r
      

      它的工作原理是只获取下一项的最后一位并将其添加到结果中。然后它获取结果的最后一位并将其设置为自身。它重复,直到它到达术语编号并返回一个数字:D

      有趣的事实: 在 99 上试试上面的函数。返回 0。999 呢? 0. 9999? 0. 继续这个:D

      【讨论】:

        【解决方案4】:

        尝试使用Pisano Period property。如果要计算最后一位,Pisano Period of 10 将是 60。知道了这一点,你可以有一个类似的函数:

        def fibonacci_sum(n):
        
            pisano = 60
        
            if n < 2: return n
        
            n %= pisano
        
            fib_arr = [1,1]
            for _ in range(n):
                fib_arr.append((fib_arr[-1] + fib_arr[-2]) % 10)
        
            return (fib_arr[-1] - 1) % 10
        

        更多信息请参考saveriogzz Github CS_Curriculum repo

        干杯!

        【讨论】:

          【解决方案5】:

          这是一个简单的 C++ 程序

          //outputs last digit of ( sum of fib number till n)
          #include<iostream>
          using namespace std;
          
          int64_t fib_sum_digit(int64_t n)
          {
              int fl[60] ={0};
              fl[0] = 0;
              fl[1] = 1;
             // int64_t sum60 = 1;
          
              for(int i = 2 ; i<60 ; i++)
              {
                  fl[i] = (fl[i-1] +fl[i-2])%10 ; 
                  //sum60 += fl[i]; 
              }
          
          
              int64_t sum = 0;
              // sum += (sum60*(n/60));               ///sum60%10 always  = 0 ;
          
              for(int i = 1; i<=(n%60); i++ )
              {
                  sum += (fl[i]);
                  //cout<<i<<","<<sum<<"->";         ///debug
              }
          
          return sum%10;
          }
          
          int main()
          {
              int64_t n;
              cin>>n;
          
              int64_t ans = fib_sum_digit(n);
              cout<<ans;
          
              return 0;
          }
          

          【讨论】:

            猜你喜欢
            • 2020-08-26
            • 1970-01-01
            • 2011-02-16
            • 1970-01-01
            • 1970-01-01
            • 2015-07-25
            • 1970-01-01
            • 2011-02-04
            • 2019-06-26
            相关资源
            最近更新 更多