一对兔子,从出生后第3个月起每个月都生一对兔子。小兔子长到第3个月后每个月又生一对兔子。假如兔子都不死,请问第1个月出生的一对兔子,至少需要繁衍到第几个月时兔子总数才可以达到 N N N对?
输入在一行中给出一个不超过10000的正整数 N N N。
在一行中输出兔子总数达到 N N N最少需要的月数。
30
9
这是一道比较经典的兔子繁衍问题,其实质是斐波那契数列问题的变形。
我们可以根据题目中的规则得到:
第0个月:0对兔子
第1个月:1对兔子
第2个月:1对兔子
第3个月:2对兔子(第1个月的兔子生了1对)
第4个月:3对兔子(第2个月的兔子生了1对,第1个月的兔子生了1对)
第5个月:5对兔子(第3个月的兔子生了1对,第2个月的兔子生了1对,第1个月的兔子生了2对)
第6个月:8对兔子(第4个月的兔子生了1对,第3个月的兔子生了2对,第2个月的兔子生了1对,第1个月的兔子生了3对)
…
可见,每个月的兔子对数都等于前两个月的兔子对数之和,即为典型的斐波那契数列。
因此,我们可以使用循环来计算兔子对数,直到达到或超过给定的目标数 N N N。时间复杂度为 O ( N ) O(N) O(N)。
值得一提的是,代码中使用了两种交换、更新变量值的方式来实现兔子繁殖过程的模拟。
temp = current
current = prev + current
prev = temp
和
prev, current = current, prev + current
这两种写法实现的功能是一样的,都是用两个变量 prev
和 current
来交替保存上个月和上上个月的兔子对数,以实现兔子繁殖过程的模拟。
第一种写法使用了一个临时变量 temp
来交换值,而第二种写法则直接利用 Python 的元组解包特性进行赋值。两者的效果是等价的,只是第一种写法更为直观,而第二种写法更为简洁。
具体来说,prev, current = current, prev + current
这条语句将当前月份的兔子对数赋给 current
,将上个月份的兔子对数赋给 prev
,等价于下面这样的代码:
new_current = prev + current
new_prev = current
prev = new_prev
current = new_current
这种用元组解包来交换变量值的方式在 Python 中非常常见,也非常方便。
无论选择哪种写法,最终都能正确地实现兔子繁殖过程的模拟。选择哪种写法主要取决于个人习惯和代码风格的偏好。
N = int(input()) # 输入N
month = 1 # 当前月份
prev = 0 # 上个月的兔子对数
current = 1 # 这个月的兔子对数
# 模拟兔子繁殖过程,直到兔子对数达到或超过输入的目标兔子对数 N
while current < N:
month += 1 # 更新月份
# # 计算这个月的兔子对数(这个月是更新后的月份)
# temp = current # 暂存上个月的对数
# current = prev + current # 这个月的兔子对数等于上上个月加上个月的
# prev = temp #更新上个月的兔子对数
prev, current = current, prev + current
print(month) # 输出最少需要的月数