Skip to content

第 15 课:循环求积 ​

循环求和的问题蛙蛙已经解决了,他觉得循环求积也可通过同样的方式处理。

15.1 循环求积的操作 ​

现在他想求从 1 乘到 10 的积,也就是求 1 × 2 × 3 × … × 10 的积,他将循环求和的程序直接拿过来用,只是把 + 号改成了 * 号,代码如下:

cpp
#include <iostream>
using namespace std;
int main()
{
    int m, n, s = 0;
    cin >> m >> n;
    for (int i = m; i <= n; i++)
    {
        s *= i;
    }
    cout << s;
    return 0;
}

编译运行后,蛙蛙发现结果是 0,这是为什么呢?

氪町博士一眼就看出了问题:s 的初始值为 0,0 乘什么的结果都是 0,所以最终的输出结果为 0。用来求积的变量 s 的初始值要为 1,这样才不会改变算式的运算结果。

循环对应的算式:s * 1 * 2 * 3 * … * 10,s 值为 1 时不会改变从 1 乘到 10 的结果。

另外需要注意的是,用来求积的变量最好是 long long 类型,因为累乘运算很容易超出 int 的取值范围。

修改完之后的代码如下:

cpp
#include <iostream>
using namespace std;
int main()
{
    int m, n;
    long long s = 1;
    cin >> m >> n;
    for (int i = m; i <= n; i++)
    {
        s *= i;
    }
    cout << s;
    return 0;
}

编译运行后,输入 1 和 10,输出的结果为 3628800。

15.2 实例讲解 ​

例 1:累乘求积 ​

输入两个正整数 m 和 n(1 ≤ m ≤ n ≤ 15),输出 m 和 n 之间(包含 m 和 n)所有整数的积。

【输入格式】输入一行,两个用空格隔开的整数 m 和 n(1 ≤ m ≤ n ≤ 15)。

【输出格式】输出一行,为 m 和 n 之间所有整数之积。

【输入样例】1 5

【输出样例】120

解析

  1. 求 m 和 n 之间所有整数的乘积,即 m * (m + 1) * (m + 2) * … * (n − 1) * n,从 m 开始,每次加 1,可循环 n − m + 1 次,从 m 乘到 n,即:
cpp
for(int i = m;i <= n;i++)
  1. 用 s 来保存运算结果。由于可能会从 1 乘到 15,而这个值是大于 2³¹ − 1(即超出 int 的取值范围)的,所以要用 long long 数据类型声明变量 s,并且需要给其赋初始值 1,即:
cpp
long long s = 1;
……
s = s * i; // 可简写为 s *= i;

参考代码

cpp
#include <iostream>
using namespace std;
int main()
{
    long long s = 1;
    int m, n;
    cin >> m >> n;
    for (int i = m; i <= n; i++)
    {
        s = s * i;
    }
    cout << s;
    return 0;
}

例 2:求阶乘 ​

输入一个正整数 n(n ≤ 15),求 n!(n! 表示的是 n 的阶乘)。

【输入格式】输入一行,一个整数 n(1 ≤ n ≤ 15)。

【输出格式】输出一行,一个整数,为 n!。

【输入样例】4

【输出样例】24

什么是阶乘?

一个正整数的阶乘是所有小于及等于该数的正整数的积,并且 0 的阶乘为 1。

自然数 n 的阶乘可写作 n!(数学表示)。

例如:

  • 0! = 1
  • 1! = 1
  • 4! = 1 × 2 × 3 × 4 = 24
  • 5! = 1 × 2 × 3 × 4 × 5 = 120
  • n! = 1 × 2 × 3 × … × (n − 1) × n

聪明的你一定学会了吧?现在你可以尝试去求 6 的阶乘、7 的阶乘分别是多少了!

解析

  1. 求 n 的阶乘,相当于 1 * 2 * 3 * … * n,从 1 乘到 n,每次乘一个数,所以一共循环 n 次,即:
cpp
for(int i = 1;i <= n;i++)
  1. 循环体内用 s 来保存结果,s 依然被声明为 long long 类型,即:
cpp
s = s * i;

参考代码

cpp
#include <iostream>
using namespace std;
int main()
{
    long long s = 1;
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        s = s * i;
    }
    cout << s;
    return 0;
}

例 3:求阶乘的和 ​

现在蛙蛙决定挑战一下自己,希望自己既能求积还能求和,于是想到了这样一个问题:输入一个正整数 n,求 1! + 2! + 3! + … + n!。

【输入格式】输入一行,一个整数 n(1 ≤ n ≤ 15)。

【输出格式】输出一行,一个整数,表示求和的结果。

【输入样例】3

【输出样例】9

解析

  1. 求 i 的阶乘。从 i 等于 1 时开始,当 i 等于 1 时计算 1 的阶乘,当 i = 2 时计算 2 的阶乘……当 i 等于 n 时求 n 的阶乘,即:
cpp
for(int i = 1;i <= n;i++)
{
    jc = jc * i; // jc 用来保存阶乘的结果
}

jc 的初始值为 1。当 i 等于 1 时,jc 为 1,再乘上 i,也就是 1,得到 1 的阶乘的结果 1;当 i 等于 2 时,jc 当前的值为 1,再乘上 i,也就是 2,得到 2 的阶乘的结果 2;当 i 等于 3 时,jc 当前的值为 2,再乘上 i,也就是 3,得到 3 的阶乘的结果 6……

  1. 我们这里要求的是阶乘的和,求完阶乘后,还要将当前 i 的阶乘累加到变量 s 中,s 的初始值为 0,即:
cpp
for(int i = 1;i <= n;i++)
{
    jc = jc * i; // 分别求了 1!、2!、3!……
    s = s + jc; // 求完一个数的阶乘后,就将其加到 s 上,s 的初始值为 0
}

参考代码

cpp
#include <iostream>
using namespace std;
int main()
{
    long long s = 0, jc = 1;
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        jc = jc * i;
        s = s + jc;
    }
    cout << s;
    return 0;
}

例 4:求次方 ​

输入两个正整数 m 和 n,求 m 的 n 次方的值。

【输入格式】输入一行,两个用空格隔开的整数 m 和 n(1 ≤ m ≤ n ≤ 15)。

【输出格式】输出一行,一个整数,表示次方的结果。

【输入样例】2 4

【输出样例】16

解析

m 的 n 次方相当于 n 个 m 相乘,只需要求 n 个 m 相乘的结果就能够得出 m 的 n 次方。用变量 cf 来保存相乘的结果,则 cf = cf * m,即:

cpp
for(int i = 1;i <= n;i++)
{
    cf = cf * m;
}

参考代码

cpp
#include <iostream>
using namespace std;
int main()
{
    long long cf = 1;
    int m,n;
    cin >> m >> n;
    for(int i = 1;i <= n;i++)
    {
        cf = cf * m;
    }
    cout << cf;
    return 0;
}

例 5:求次方的和 ​

输入两个正整数 m 和 n,求 1 + m + m² + m³ + … + mⁿ。

【输入格式】输入一行,两个用空格隔开的整数 m 和 n(1 ≤ m ≤ n ≤ 15)。

【输出格式】输出一行,一个整数,表示求和的结果。

【输入样例】2 4

【输出样例】31

解析

这里用 s 来保存求和的结果,cf 保存当前 n 个 m 相乘的结果。将多个 cf 的和保存到 s 中,即为次方和,即:

cpp
for(int i = 1;i <= n;i++)
{
    cf = cf * m;
    s = s + cf;
}

参考代码

cpp
#include <iostream>
using namespace std;
int main()
{
    long long cf = 1, s = 1;
    int m, n;
    cin >> m >> n;
    for (int i = 1; i <= n; i++)
    {
        cf = cf * m;
        s = s + cf;
    }
    cout << s;
    return 0;
}

基于 MIT 协议发布