在C++程序中,累乘的思想应用很广泛,很多情况下累加、累乘和累除相互结合使用可以解决很多问题。
实战训练1---求阶乘
问题描述:
给定正整数 n,求从 1到 n 的每一个整数的阶乘。
输入格式:
输入一行,包含一个正整数 (1<n≤12)。
输出格式:
输出 n行,每行有两个数,分别是 i 和 i 的阶乘,两个数之间用空格隔开。
输入输出样例:
|------|------------------------|
| 输入样例 | 输出样例 |
| 5 | 1 1 2 2 3 6 4 24 5 120 |
问题分析:
求1到n这n个数的和sum,使用累加的思想,依次将这n个数累加到sum中;对于阶乘的定义n!=1*2*3*4......*n(0的阶乘为1),可以看出n的阶乘是这n个数进行相乘,仿造累加求和,累乘首先定义一个乘积变量facn,并初始化为1,使用for循环来累乘,循环变量i的初始值为1,终值为n,在循环体内将i累乘到facn中,对循环变量更新使用自增运算每次加1,具体程序代码如下:
cpp
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,facn=1;//定义整数变量n和阶乘变量facn并初始化为1
cin>>n;//输入n
for(int i=1;i<=n;i++){//定义循环变量i并初始化为1,终值为n,循环更新为++
facn *= i;//i累乘到阶乘变量facn中
cout<<i<<' '<<facn<<endl; //输出i以及i对应的阶乘
}
return 0;
}
**思考1:**为什么题目中将n的取值范围限定为:1<n<=12,如果n的值超过12,会怎么样呢?假设程序运行起来之后,输入n的值为18,程序的运行结果如下:
cpp
1 1
2 2
3 6
4 24
5 120
6 720
7 5040
8 40320
9 362880
10 3628800
11 39916800
12 479001600
13 1932053504
14 1278945280
15 2004310016
16 2004189184
17 -288522240
18 -898433024
19 109641728
根据运行结果,可以得出n在12之前(包括12),n的阶乘都是正确的,从13开始,n的阶乘值都是错误,17和18的阶乘甚至出现了负数,原因是阶乘的结果超出了int类型的表示范围(int的类型可表示的范围为:-2147483648到2147483647),这时可将facn定义为long long类型,具体程序代码如下:
cpp
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;//定义整数变量n
long long facn=1;//定义阶乘变量facn并初始化为1
cin>>n;//输入n
for(int i=1;i<=n;i++){//定义循环变量i并初始化为1,终值为n,循环更新为++
facn *= i;//i累乘到阶乘变量facn中
cout<<i<<' '<<facn<<endl; //输出i以及i对应的阶乘
}
return 0;
}
将上述题目修改为求阶乘和,即1!+2!+3!+......+n!,结合累乘和累加的思想来解决,具体程序代码如下:
cpp
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;//定义整数变量n
long long facn=1,sum=0;//定义阶乘变量facn并初始化为1 和 累加和变量sum并初始化为0
cin>>n;//输入n
for(int i=1;i<=n;i++){//定义循环变量i并初始化为1,终值为n,循环更新为++
facn *= i;//i累乘到阶乘变量facn中
sum += facn;//将阶乘变量累加到sum中
}
cout<<sum<<endl;//输出阶乘和
return 0;
}
实战训练2---求学生的平均年龄
问题描述:
小明班上有 n 个学生,现给出每名学生的年龄且保证是一个整数,求班上全部学生的平均年龄,且保留到小数点后两位。
输入格式:
第一行有一个整数n(1≤n≤100),表示学生的人数。其后 n 行每行有 1 个整数,表示每个学生的年龄,取值为15到25。
输出格式:
输出一行,该行包含一个浮点数,为要求的平均年龄,保留到小数点后两位。
输入输出样例:
|------------|-------|
| 输入样例 | 输出样例 |
| 3 17 18 18 | 17.67 |
问题分析:
根据题意,需要将这n个学生的年龄依次累加到年龄和中,需要累加n次,可以使用for循环来解决,循环变量初始值为1,终值为n,循环变量更新执行自增运算,结束循环之后,将全部的年龄和除以n,得到最终的平均年龄,由于不一定能除尽,因此平均年龄设置为浮点类型,同时注意在进行除法运算之前进行类型转换,具体程序代码如下:
cpp
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,sum=0;//定义学生个数n和年龄和sum并初始化为0
double avg;//定义学生平均年龄
scanf("%d",&n); //输入学生个数n
for(int i=1;i<=n;i++){//定义循环变量i并初始化为1,终值为n,循环更新为++
int tmp;//定义学生年龄tmp
scanf("%d",&tmp);// 输入学生年龄
sum += tmp;//将学生年龄累加到sum中
}
avg = sum *1.0/n;//计算平均年龄,首先将sum乘以1.0转换成double类型再去除以n
printf("%0.2lf\n",avg);//格式化输出学生平均年龄 ,小数点后面保留2位
return 0;
}
**思考:**如果将上述题目修改为输入n个浮点数,计算这n个数的均值,并输出,小数点后面保留四位小数,则对上述代码就行修改,具体程序代码如下:
cpp
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;//定义浮点数的个数变量n
double sum=0.0,avg;//定义n个浮点数的和变量sum并初始化为0 以及浮点数的平均数avg
scanf("%d",&n); //输入浮点数个数n
for(int i=0;i<n;i++){
double tmp;//定义浮点数
scanf("%lf",&tmp);//输入浮点数
sum += tmp;//将浮点数的值累加到sum变量
}
avg = sum /n;//计算浮点数的平均数
printf("%0.4lf\n",avg);//格式化输出浮点数平均数,小数点后面保留2位
return 0;
}