月落乌啼算钱(斐波那契数列)

GitHub跳转原题关系图返回列表

用两个整数变量迭代计算斐波那契数,再用格式化输出保留两位小数。

OJ: luogu

题目 ID: P1720

难度:入门

标签:数学递推python

日期: 2026-07-15 18:35

题意

输入自然数 n,输出斐波那契数列第 nF_n,并保留两位小数。

本题给出了通项公式,但数据范围只有 0 <= n <= 48,也可以直接用递推计算。

思路

斐波那契数列满足:

text
F_0 = 0
F_1 = 1
F_n = F_{n-1} + F_{n-2}

用两个变量维护相邻两项:

  • previous 表示当前要输出位置之前的值;
  • current 表示下一项。

每循环一次,执行:

text
previous, current = current, previous + current

循环 n 次后,previous 就是 F_n

最后题目要求输出实数且保留两位小数,因此用 f"{previous:.2f}" 格式化。

这题的直接递推已经足够简单,brute.py 与正解没有区别,所以不创建额外暴力文件。

Python 知识

  • /home/rainboy/mycode/hugo-blog/content/program_language/python/input_output_and_strings.md:使用 int(input()) 读取整数。
  • /home/rainboy/mycode/hugo-blog/content/program_language/python/math_tools.md:Python int 是任意精度整数,本题 F_48 不会有溢出问题。
  • previous, current = current, previous + current 是 Python 的多变量同时赋值,适合写递推状态滚动。
  • f"{previous:.2f}" 表示按两位小数输出。

代码

python
n = int(input())

previous = 0
current = 1

for _ in range(n):
    previous, current = current, previous + current

print(f"{previous:.2f}")
cpp
/**
 * Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
 * rbook: -> https://rbook.roj.ac.cn  https://rbook2.roj.ac.cn
 * rainboy的学习导航网站: https://idx.roj.ac.cn
 * create_at: 2026-07-27 00:00
 * update_at: 2026-07-27 00:00
 */

#include <bits/stdc++.h>
using namespace std;

int main() {
    int n; // 斐波那契数列第 n 项
    cin >> n;
    long long previous = 0; // F(0)
    long long current = 1;  // F(1)
    // 滚动迭代:每次前进一步,previous 变成 current,current 变成两者之和
    for (int i = 0; i < n; i++) {
        long long next = previous + current;
        previous = current;
        current = next;
    }
    // 题目要求以实数形式保留两位小数输出
    printf("%.2f\n", (double)previous);
    return 0;
}

Pythonic 写法

斐波那契滚动:

python
n=int(input())
a=b=1
for _ in range(n-1):
    a,b=b,a+b
print(f"{a:.2f}" if n else "0.00")

复杂度

循环 n 次,时间复杂度是 O(n)O(n);只用两个变量,空间复杂度是 O(1)O(1)

总结

虽然题面给了通项公式,但在 OJ 里小范围斐波那契更适合用整数递推。这样避免浮点误差,也更容易解释和模仿。