题目链接

牛牛学数列2

题目描述

牛牛需要计算调和级数的前 n 项和:H(n) = 1 + 1/2 + 1/3 + ... + 1/n

输入描述: 输入一个正整数 n (1 ≤ n ≤ 1000)。

输出描述: 输出一个浮点数,表示 H(n) 的值。答案与标准答案的绝对误差或相对误差在 1e-6 以内被认为是正确的。

解题思路

本题要求计算调和级数的部分和。由于输入 n 的最大值只有 1000,这是一个相对较小的数字,因此我们可以直接使用循环进行模拟计算,而无需寻找复杂的数学公式。

  1. 数据类型: 结果是小数,所以我们需要一个浮点数类型(如 C++ 中的 double 或 Java 中的 double)的变量 sum 来累加求和,并将其初始化为 0.0。

  2. 循环: 我们需要一个从 1 到 n 的循环。在循环的每一步中,变量 i 代表当前项的分母。

  3. 浮点数除法: 在计算每一项 1/i 时,必须执行浮点数除法。在 C++ 和 Java 等语言中,如果直接写 1 / i,而 i 是一个整数,编译器会执行整数除法,结果会被截断为 0(当 i > 1 时),这会导致错误的结果。为了避免这种情况,我们必须确保除法操作中的至少一个操作数是浮点数。最简单的方法是写成 1.0 / i

  4. 累加: 将每一步计算出的 1.0 / i 的值累加到 sum 变量中。

  5. 输出: 循环结束后,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 的循环。
  • 空间复杂度:,只使用了常数级别的额外空间来存储变量。