求分数序列和

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

维护当前项分母 p、分子 q,每轮累加 q/p 后把 (p,q) 更新为 (q,p+q),迭代 n 次并保留 4 位小数。

OJ: roj

题目 ID: 1078

难度:入门

标签:入门递推数学浮点数python

创建: 2026-09-29 17:43

更新: 2026-10-05 00:20

题目描述

分数序列满足 q1=2q_1=2,p1=1p_1=1,qi+1=qi+piq_{i+1}=q_i+p_i,pi+1=qip_{i+1}=q_i。给定 n (n≤30)n\ (n\le 30),求前 nn 项 qipi\frac{q_i}{p_i} 之和,保留 4 位小数(输入一行 nn,输出一行浮点数)。

样例输入 2,样例输出 3.5000。

思路

只需维护当前项的分母 pp、分子 qq:每轮先累加 q/pq/p,再用临时变量把 (p,q)(p,q) 更新为 (q, p+q)(q,\,p+q),迭代 nn 次即可。

参考代码

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 17:43
# update_at: 2026-09-29 17:50

import sys
from collections.abc import Iterator


def fraction_terms(n: int) -> Iterator[float]:
    """依次产出分数序列的前 n 项:分母接上一项的分子,新分子是两者之和。"""
    p, q = 1, 2  # p_1 = 1,q_1 = 2
    for _ in range(n):
        yield q / p
        p, q = q, p + q  # 下一项的分母换成当前项的分子


def solve() -> None:
    data = iter(map(int, sys.stdin.buffer.read().split()))
    n = next(data)  # 求和的项数
    print(f"{sum(fraction_terms(n)):.4f}")


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 00:20
 * update_at: 2026-10-05 00:20
 */
// main.cpp:按递推式生成分数序列的前 n 项并求和,保留 4 位小数。
#include <cstdio>

typedef long long ll;

int main() {
    ll n;
    if (scanf("%lld", &n) != 1) {
        return 0;
    }

    ll p = 1;    // 当前项的分母 p_i,初始 p_1 = 1
    ll q = 2;    // 当前项的分子 q_i,初始 q_1 = 2
    double sum = 0.0;
    for (ll i = 1; i <= n; i++) {
        sum += 1.0 * q / p; // 累加第 i 项 q_i / p_i
        ll nextq = q + p;   // 下一项的分子 = 当前项分子 + 当前项分母
        p = q;              // 下一项的分母 = 当前项分子
        q = nextq;
    }
    printf("%.4f\n", sum);
    return 0;
}