这篇文章参考了许多资料,其中来自博客的有 《斐波那契数列的5种python解法》1,原文作者 :AI算法工程师YC,在这里简单记录一下学习过程。
斐波纳契数列是python练习时经常遇见的一个很基础的问题,在网上也有许许多多的解法,在备战蓝桥杯的python个人赛,我也刚好遇见了有关斐波那契数列的问题,前前后后用了多种方法,才实现了通过系统100%的测试,达到时长和内存的要求。
环境为 python3.7.0,用的python3.7.0自带的IDLE,无扩展库。
问题
Fibonacci数列 斐波纳契(一种整数数列)
资源限制
时间限制:1.0s 内存限制:256.0MB
python中的内置函数
问题描述
Fibonacci数列的递推公式为:Fn=Fn-1+Fn-2,其中F1=F2=1。
当n比较大时,Fn也非常大,现在我们想知道,Fn除以10007的余数是多少。
输入格式
输入包含一个整数n。
输出格式
输出一行,包含一个整数,表示Fn除以10007的余数。
样例输入
10
样例输出
55
样例输入
22
样例输出
7704
数据规模与约定
1 <= n <= 1,000,000。
我们的测试输入数据分别是
1
2
10
55
100
500
999
9999
99999
999999
共十组输入数据
def fib_recur(n):
assert n >= 0, "n > 0"
if n == 1 or n == 2:
return 1
else:
return fib_recur( n - 1 ) % 10007 + fib_recur( n - 2 ) % 10007
n = eval(input())
print(fib_recur(n))
只能通过30%的测试,最大递归深度在比较中超过,产生递归错误。
def Fibonacci(n):
a,b = 0,1
for i in range(n):
a, b = b, a + b
return a % 10007
n = eval(input())
print(Fibonacci(n))
在输入999999超时,不能满足比较大的项的斐波纳契数列,不过满足一般情况下,通了90%的测试。
def Fibonacci(max):
a, b = 0, 1
while max > 0:
a, b = b, a + b
max -= 1
yield a
n = eval(input())
for i in Fibonacci(n):
num = i % 10007
print(num)
通过80%的测试,接下来的测试都超时。
class Fibonacci(object):
def __init__(self, n):
self.n = n
self.current = 0
self.a = 0
self.b = 1
def __next__(self):
if self.current < self.n:
self.a, self.b = self.b, self.a + self.b
self.current += 1
return self.a
else:
raise StopIteration
def __iter__(self):
return self
n = eval(input())
if __name__ == '__main__':
fib = Fibonacci(n)
for num in fib:
num1 = num % 10007
print(num1)
代码片长,不易理解,且只能通过80%的测试。
import numpy as np
def pow(n):
a = np.array([[1,0],[0,1]])
b = np.array([[1,1],[1,0]])
n -= 1
while(n > 0):
if (n % 2 == 1):
a = np.dot(b, a)
b = np.dot(b, b)
n >>= 1
return a[0][0]
n = eval(input())
print(pow(n)%10007)
因为numpy不是python的内置函数,是扩展库,不能通过测试,但本身代码是可行的,可通过所有测试数据,运行速度满足1s以内。
from functools import reduce
def Fibonacci(n):
def m1(a,b):
m=[[],[]]
m[0].append(a[0][0]*b[0][0]+a[0][1]*b[1][0])
m[0].append(a[0][0]*b[0][1]+a[0][1]*b[1][1])
m[1].append(a[1][0]*b[0][0]+a[1][1]*b[1][0])
m[1].append(a[1][0]*b[1][0]+a[1][1]*b[1][1])
return m
def m2(a,b):
m=[]
m.append(a[0][0]*b[0][0]+a[0][1]*b[1][0])
m.append(a[1][0]*b[0][0]+a[1][1]*b[1][0])
return m
return m2(reduce(m1,[[[0,1],[1,1]] for i in range(n)]),[[0],[1]])[0]
n = eval(input())
print(Fibonacci(n)%10007)
方法难想到,我也看不懂,且只能通过80%的测试,不满足需求。
n = eval(input())
num = 5 ** (1/2)
Fib_n1 = ( ( 1 + num ) / 2 )** n
Fib_n2 = ( ( 1 - num ) / 2 )** n
Fib_n = 1 / num * ( Fib_n1 - Fib_n2 )
put_number = int(Fib_n % 10007)
print(put_number)
只能通过40%的测试,会数据溢出,因为精度太大
n=eval(input())
a=[]
a.append(1)
a.append(1)
for i in range(2,n):
a.append( (a[i-1]+a[i-2]) % 10007 )
print(a[n-1])
通过100%的测试,满足要求,方法简单
https://blog.csdn.net/qq_36134437/article/details/103019332 ↩︎