题目链接
题目描述
牛牛需要计算调和级数的前 n
项和:H(n) = 1 + 1/2 + 1/3 + ... + 1/n
。
输入描述:
输入一个正整数 n
(1 ≤ n ≤ 1000)。
输出描述:
输出一个浮点数,表示 H(n)
的值。答案与标准答案的绝对误差或相对误差在 1e-6
以内被认为是正确的。
解题思路
本题要求计算调和级数的部分和。由于输入 n
的最大值只有 1000,这是一个相对较小的数字,因此我们可以直接使用循环进行模拟计算,而无需寻找复杂的数学公式。
-
数据类型: 结果是小数,所以我们需要一个浮点数类型(如 C++ 中的
double
或 Java 中的double
)的变量sum
来累加求和,并将其初始化为 0.0。 -
循环: 我们需要一个从 1 到
n
的循环。在循环的每一步中,变量i
代表当前项的分母。 -
浮点数除法: 在计算每一项
1/i
时,必须执行浮点数除法。在 C++ 和 Java 等语言中,如果直接写1 / i
,而i
是一个整数,编译器会执行整数除法,结果会被截断为 0(当i > 1
时),这会导致错误的结果。为了避免这种情况,我们必须确保除法操作中的至少一个操作数是浮点数。最简单的方法是写成1.0 / i
。 -
累加: 将每一步计算出的
1.0 / i
的值累加到sum
变量中。 -
输出: 循环结束后,
sum
变量中存储的就是最终结果。直接输出这个变量即可。为了保证输出格式满足题目示例,可以格式化输出,保留若干位小数(例如6位)。
这个直接迭代的方法对于本题的数据范围来说,效率完全足够。
代码
#include <iostream>
#include <iomanip> // 包含格式化输出所需的头文件
using namespace std;
int main() {
int n;
cin >> n;
double sum = 0.0;
for (int i = 1; i <= n; ++i) {
// 使用 1.0 来确保进行浮点数除法
sum += 1.0 / i;
}
// 格式化输出,保留6位小数
cout << fixed << setprecision(6) << sum << endl;
return 0;
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
double sum = 0.0;
for (int i = 1; i <= n; i++) {
// 使用 1.0 来确保进行浮点数除法
sum += 1.0 / i;
}
// 使用 printf 格式化输出,保留6位小数
System.out.printf("%.6f%n", sum);
}
}
# 读取输入的n
n = int(input())
total_sum = 0.0
for i in range(1, n + 1):
# Python 3的 / 运算符默认执行浮点数除法
total_sum += 1 / i
# 使用 f-string 格式化输出,保留6位小数
print(f"{total_sum:.6f}")
算法及复杂度
- 算法:迭代求和。
- 时间复杂度:
,因为代码的核心是一个从 1 循环到
n
的循环。 - 空间复杂度:
,只使用了常数级别的额外空间来存储变量。