top1编程
← 返回题目
题解

奇数求和

1 条题解

  • 0
    @ 2026-8-6 0:54:26

    P4755 奇数求和(入门)

    解题思路

    这道题要求我们把 0 到 n 之间所有的奇数加起来,而且要求用递归来做。比如 n = 3,奇数是 1 和 3,1 + 3 = 4,所以答案是 4。

    递归的思路是"大事化小"。我们可以定义一个函数 sumOdd(n),它表示"1 到 n 之间所有奇数之和"。怎么把这个问题变小呢?分两种情况:

    • 如果 n 是偶数,比如 n = 4,那么 4 本身不是奇数,不用加,答案和"1 到 3 的奇数和"一样,也就是 sumOdd(4) = sumOdd(3);
    • 如果 n 是奇数,比如 n = 5,那么 5 是奇数,一定要加上,然后再求"1 到 3 的奇数和",也就是 sumOdd(5) = 5 + sumOdd(3)。

    写成式子就是:n 是偶数时 sumOdd(n) = sumOdd(n-1);n 是奇数时 sumOdd(n) = n + sumOdd(n-2)。

    函数什么时候停下来呢?当 n 小于等于 0 时,已经没有奇数了,直接返回 0。这就是递归的"出口",保证程序不会无限循环下去。

    可以把这个递归想象成"倒着爬楼梯":每次都把 n 减小一点,一直减到 0,再把一路上捡到的奇数一个个加起来。这个思路非常清晰,也不容易出错。奇数求和还有一个巧妙的规律:1 到 n 的所有奇数之和等于 (n+1)/2 的平方,不过题目要求我们用递归,所以我们就老老实实按递归来做。

    参考代码

    // 奇数求和:用递归求0到n之间所有奇数之和(含n本身)
    #include <iostream>
    using namespace std;
    
    // 递归求1到n所有奇数之和
    int sumOdd(int n) {
        if (n <= 0) return 0;                 // 没有奇数可加了
        if (n % 2 == 0) return sumOdd(n - 1); // n是偶数不加入,继续看n-1
        return n + sumOdd(n - 2);             // n是奇数就加上,再往前数2
    }
    
    int main() {
        int n;
        cin >> n;
        cout << sumOdd(n) << endl;
        return 0;
    }
    

    复杂度分析

    每次调用递归,n 要么减少 1,要么减少 2,所以最多调用大约 n 次,时间复杂度是 O(n)。n 最大是 100,100 次运算瞬间完成。递归的深度也就是 n 层,空间占用 O(n)。这道题不用任何数组和循环,用"递归"这个工具,把求和这种本来用循环就能解决的问题换了一种漂亮的写法。

    • 1