题解:洛谷 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
【核心思想】
-
问题分析:给定整数 \(k\),求最小的 \(n\) 使得调和级数 \(S_n = 1 + \frac{1}{2} + \frac{1}{3} + \cdots + \frac{1}{n} > k\)。调和级数发散但增长极慢,需逐项累加直至超过阈值。
-
算法选择:
- 逐项累加:从 \(n=1\) 开始,不断加上 \(\frac{1}{n}\),直到累加和 \(s > k\)
-
关键步骤:
- 读入数据:
cin >> k - 初始化:
n = 1, s = 0.0 - 循环累加(当
s <= k):s += 1.0 / n:加上当前项(注意1.0保证浮点除法)n++:项数递增
- 输出结果:
n - 1(因循环结束时 \(n\) 已多自增一次)
- 读入数据:
-
时间/空间复杂度:
- 时间复杂度:\(O(n)\),\(n\) 为答案值,调和级数增长极慢(\(S_n \approx \ln n + \gamma\)),故 \(n \approx e^k\)
- 空间复杂度:\(O(1)\),仅需常数个变量
-
级数累加的核心思想:
- 浮点除法注意:
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
浙公网安备 33010602011771号