兔群繁殖之谜
问题描述
生物学家小 R 正在研究一种特殊的兔子品种的繁殖模式。这种兔子的繁殖遵循以下规律:
- 每对成年兔子每个月会生育一对新的小兔子(一雌一雄)。
- 新生的小兔子需要一个月成长,到第二个月才能开始繁殖。
- 兔子永远不会死亡。
小 R 从一对新生的小兔子开始观察。他想知道在第 A
个月末,总共会有多少对兔子。
请你帮助小 R 编写一个程序,计算在给定的月份 A
时,兔子群体的总对数。
注意:
- 初始时有 1 对新生小兔子。
- 第 1 个月末有 1 对兔子:原来那对变成了成年兔子,并开始繁殖。
- 第 2 个月末有 2 对兔子:原来那 1 对成年兔子,繁殖了 1 对新生的小兔子。
- 从第 3 个月开始,兔子群体会按照上述规律增长。
输入
一个整数 A
(1 ≤ A ≤ 50),表示月份数。
返回
一个长整数,表示第 A
个月末兔子的总对数。
测试样例
样例1:
输入:
A = 1
返回:1
样例2:
输入:
A = 5
返回:8
样例3:
输入:
A = 15
返回:987
题目解析
这道题是非常经典的斐波那契数列,其又被称为黄金分割数列。其特点就是数列中的每一项都等于前两项之和。通常,斐波那契数列的起始数字为 0 和 1,从第三项开始呈现上述规律。用数学公式表达即 F(n) = F(n-1) + F(n-2),其中n>=2,且F(0)=0,F(1)=1。
举个样例:当A=5时即是求第5个月时有多少对兔子,推算:
- 第一个月 1对
- 第二个月 2对
- 第三个月 3对 = 第一个月 + 第二个月
- 第四个月 5对 = 第二个月 + 第三个月
- 第五个月 8对 = 第三个月 + 第四个月
而有些特殊情况 例如 A = 1 时,就按照题目规定的 第一个月为1对
以及 A =2 时也按题目规定 第二个月2对 即可
个人解答
def solution(A):
if A <= 2:
return A
# 初始化前两个月的兔子对数
prev1, prev2 = 2, 1
# 从第3个月开始计算
for _ in range(3, A + 1):
current = prev1 + prev2
prev2 = prev1
prev1 = current
return prev1
if __name__ == "__main__":
# Add your test cases here
print(solution(1) == 1)
print(solution(5) == 8)
print(solution(15) == 987)
实际上这道题还可以用递归来做
- 递归是一种在函数定义中调用函数自身的编程技巧。它是一种解决问题的方法,将一个大型复杂的问题逐步分解为相同类型的较小子问题,直到子问题简单到可以直接求解。
以下是递归的写法
def fibonacci(A):
# 基本情况
if A == 1:
return 1
elif A == 2:
return 2
# 递归情况
else:
return fibonacci(A - 1) + fibonacci(A - 2)
def solution(A):
return fibonacci(A)
if __name__ == "__main__":
# Add your test cases here
print(solution(1) == 1)
print(solution(5) == 8)
print(solution(15) == 987)
小结
这题有意思的是可以用递归来做,以前学斐波那契数列时,老师都会让我们用递归的方式来写,顺便把递归学了,但实际上也可以不用递归写,也算是比较有趣的一点吧。