第 15 课:循环求积
循环求和的问题蛙蛙已经解决了,他觉得循环求积也可通过同样的方式处理。
15.1 循环求积的操作
现在他想求从 1 乘到 10 的积,也就是求 1 × 2 × 3 × … × 10 的积,他将循环求和的程序直接拿过来用,只是把 + 号改成了 * 号,代码如下:
#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 的取值范围。
修改完之后的代码如下:
#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
解析
- 求 m 和 n 之间所有整数的乘积,即 m * (m + 1) * (m + 2) * … * (n − 1) * n,从 m 开始,每次加 1,可循环 n − m + 1 次,从 m 乘到 n,即:
for(int i = m;i <= n;i++)- 用 s 来保存运算结果。由于可能会从 1 乘到 15,而这个值是大于 2³¹ − 1(即超出 int 的取值范围)的,所以要用 long long 数据类型声明变量 s,并且需要给其赋初始值 1,即:
long long s = 1;
……
s = s * i; // 可简写为 s *= i;参考代码
#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 的阶乘分别是多少了!
解析
- 求 n 的阶乘,相当于 1 * 2 * 3 * … * n,从 1 乘到 n,每次乘一个数,所以一共循环 n 次,即:
for(int i = 1;i <= n;i++)- 循环体内用 s 来保存结果,s 依然被声明为 long long 类型,即:
s = s * i;参考代码
#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
解析
- 求 i 的阶乘。从 i 等于 1 时开始,当 i 等于 1 时计算 1 的阶乘,当 i = 2 时计算 2 的阶乘……当 i 等于 n 时求 n 的阶乘,即:
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……
- 我们这里要求的是阶乘的和,求完阶乘后,还要将当前 i 的阶乘累加到变量 s 中,s 的初始值为 0,即:
for(int i = 1;i <= n;i++)
{
jc = jc * i; // 分别求了 1!、2!、3!……
s = s + jc; // 求完一个数的阶乘后,就将其加到 s 上,s 的初始值为 0
}参考代码
#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,即:
for(int i = 1;i <= n;i++)
{
cf = cf * m;
}参考代码
#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 中,即为次方和,即:
for(int i = 1;i <= n;i++)
{
cf = cf * m;
s = s + cf;
}参考代码
#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;
}