全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之循环结构(for循环语句)(三)

在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;
}
相关推荐
Coovally AI模型快速验证1 小时前
【YOLO算法改进】ALSS-YOLO:无人机热红外图像|野生动物小目标检测
人工智能·算法·yolo·目标检测·机器学习·目标跟踪·无人机
yonuyeung1 小时前
代码随想录算法【Day7】
算法·leetcode·哈希算法
湫ccc2 小时前
《机器学习》KNN算法实现手写数字识别
人工智能·算法·机器学习
蚰蜒螟2 小时前
mysql8 从C++源码角度看 客户端发送的sql信息 mysql服务端从网络读取到buff缓存中
网络·c++·sql
老大白菜2 小时前
python 选择排序(Selection Sort)
python·算法·排序算法
酒鬼猿2 小时前
基础算法--滑动窗口
算法
叶子2024223 小时前
labelme下载
java·jvm·算法
计算机萍萍学姐3 小时前
ArrayList和LinkedList的区别是什么?
java·数据结构·算法
jf加菲猫3 小时前
条款35:考虑虚函数以外的其它选择(Consider alternatives to virtual functions)
开发语言·c++