我试图找到斐波那契数列之和的最后一位。我将总和计算为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))
答案 0 :(得分:1)
斐波纳契数repeats的最终数字序列,其周期为60。因此,您可以优化对F((n+2) % 60) - 1
的n个项之和的计算。另外,要保持在整数范围内,您只能保留每个术语的最后一位:
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]
答案 1 :(得分:1)
查看此表:http://www.maths.surrey.ac.uk/hosted-sites/R.Knott/Fibonacci/fibtable.html
请注意,fib(60)
的最后一位是0
,而fib(61)
的最后一位是1
,与fib(0)
和fib(1)
相同,因此从{ {1}}的最后一位开始重复,因此您可以计算60
的最后一位而不是fib(n%60)
。
例如,fib(n)
和fib(115)
的最后一位数字相同,并且等于fib(55)
。
答案 2 :(得分:0)
以下代码专门针对最后一位数字进行了优化:
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
答案 3 :(得分:0)
尝试使用Pisano Period property。如果要计算最后一位数字,则Pisano周期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。
干杯!
答案 4 :(得分:0)
这是一个简单的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;
}