题解:洛谷 P1035 级数求和

【题目来源】

洛谷:P1035 [NOIP 2002 普及组] 级数求和 - 洛谷(luogu.com.cn)

【题目描述】

已知:\(S_n=1+\frac{1}{2}+\frac{1}{3}+\dots+\frac{1}{n}\)。显然对于任意一个整数 \(k\),当 \(n\) 足够大的时候,\(S_n\gt k\)

现给出一个整数 \(k\),要求计算出一个最小的 \(n\),使得 \(S_n\gt k\)

【输入】

一个正整数 \(k\)

【输出】

一个正整数 \(n\)

【输入样例】

1

【输出样例】

2

【核心思想】

  1. 问题分析:给定整数 \(k\),求最小的 \(n\) 使得调和级数 \(S_n = 1 + \frac{1}{2} + \frac{1}{3} + \cdots + \frac{1}{n} > k\)。调和级数发散但增长极慢,需逐项累加直至超过阈值。

  2. 算法选择

    • 逐项累加:从 \(n=1\) 开始,不断加上 \(\frac{1}{n}\),直到累加和 \(s > k\)
  3. 关键步骤

    • 读入数据cin >> k
    • 初始化n = 1, s = 0.0
    • 循环累加(当 s <= k):
      • s += 1.0 / n:加上当前项(注意 1.0 保证浮点除法)
      • n++:项数递增
    • 输出结果n - 1(因循环结束时 \(n\) 已多自增一次)
  4. 时间/空间复杂度

    • 时间复杂度:\(O(n)\)\(n\) 为答案值,调和级数增长极慢(\(S_n \approx \ln n + \gamma\)),故 \(n \approx e^k\)
    • 空间复杂度:\(O(1)\),仅需常数个变量
  5. 级数累加的核心思想

    • 浮点除法注意1.0 / n 而非 1 / n,确保进行浮点除法而非整数除法(后者恒为 0)
    • 循环终止条件s <= k 时继续,一旦 s > k 立即停止,保证 \(n\) 的最小性
    • 答案修正:循环内先累加后自增,退出时 \(n\) 比实际项数多 1,需减 1 修正
    • 调和级数性质:虽然发散,但增长极其缓慢(\(k=1\)\(n=2\)\(k=15\)\(n\) 已超过百万)
    • 适用于级数求和、阈值搜索、浮点累加类入门问题

【算法标签】

入门 #数学

【代码详解】

#include <bits/stdc++.h>  // 包含标准库头文件
using namespace std;

int main()
{
    int n = 1, k;      // n: 当前项数,从1开始计数;k: 用户输入的阈值
    double s = 0;      // s: 调和级数的累加和

    cin >> k;          // 输入阈值k

    // 循环计算调和级数,直到和s超过阈值k
    while (s <= k)
	{
        s += 1.0 / n;  // 将当前项1/n加到总和s中
        n++;           // 移动到下一项
    }

    // 输出结果:n-1是因为循环结束时n已经自增了一次
    cout << n - 1;

    return 0;
}

【运行结果】

1
2
posted @ 2026-08-05 15:44  团爸讲算法  阅读(39)  评论(0)    收藏  举报