按定义预处理 F(1..20),每个询问 O(1) 回答。
OJ: roj
题目 ID: 1201
难度:入门
标签:入门递推递归记忆化搜索python
创建: 2026-09-29 23:16
更新: 2026-10-05 05:26
题目描述
菲波那契数列的第 1、2 个数都为 1,之后每个数都等于前面 2 个数之和。输入第 1 行是测试数据的组数
样例输入 4 5 2 19 1,样例输出 5 1 4181 1(输入输出均为每行一个数)。
思路
按定义从 ll 存也不存在溢出问题。
参考代码
Python 版:
python
#!/usr/bin/env python3
# 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-09-29 23:16
# update_at: 2026-09-29 23:28
import sys
from functools import cache
@cache
def fib(a: int) -> int:
"""返回斐波那契数列第 a 项:F(1)=F(2)=1,F(a)=F(a-1)+F(a-2)。"""
return 1 if a <= 2 else fib(a - 1) + fib(a - 2) # 递归定义,@cache 把算过的 a 记下来
def solve() -> None:
data = iter(map(int, sys.stdin.buffer.read().split()))
n = next(data) # 题面的测试数据组数
print('\n'.join(str(fib(next(data))) for _ in range(n)))
if __name__ == "__main__":
solve()C++ 版(同一算法):
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-10-05 05:26
* update_at: 2026-10-05 05:26
*/
#include <cstdio>
typedef long long ll;
ll fib[25]; // fib[i] 表示菲波那契数列第 i 项,下标从 1 开始和题面对应
// 自底向上递推预处理:F(1)=F(2)=1,F(a)=F(a-1)+F(a-2)
void init_fib() {
fib[1] = 1;
fib[2] = 1;
for (int i = 3; i <= 20; ++i)
fib[i] = fib[i - 1] + fib[i - 2];
}
int main() {
init_fib(); // a<=20,预处理一遍后面每个询问 O(1) 回答
int n;
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
int a;
scanf("%d", &a);
printf("%lld\n", fib[a]);
}
return 0;
}