目录
一,题目
二,思路
三,代码
一,题目
描述
用高精度计算出 S=1!+2!+3!+…+n!(n≤50),其中“!”表示阶乘,例如:5!=5×4×3×2×1。
输入正整数n,输出计算结果S。
输入描述
一个正整数n。
输出描述
计算结果S。
用例输入 1
5
用例输出 1
153
二,思路
- 先产生阶乘:1!,2!,3!,4!,5!...n!,生成阶乘相关的代码请参考下面的文章👇
c++习题30-求10000以内N的阶乘-CSDN博客 - 产生每一次的阶乘之后,要将结果保存起来,这个时候就需要对之前文章中的代码进行修改:
1) 最外层的控制阶乘个数的循环不变,内层需要有两个并列的循环,前一个循环用于产生阶乘数值,后一个循环将每一次的阶乘数值相加。
2)存储每一次阶乘数值的容器变量 ,声明在控制阶乘个数的循环和求阶乘数值的循环中间(每一次的阶乘数值都不一样需要重新定义,而在求阶乘数值的时候不需要重新定义,之前的结果要参与运算)。
3)由于阶乘最大可以是50的阶乘(<=50),而50的阶乘有60+的位数,因此需要一个可以存储这个大整数的数据类型,建议选择整型的vector容器会比较方便。因为是用来存储输出结果的容器变量 ,所以需要将容器变量 s 声明在外层for循环的前面,用于最后的输出。
4)对阶乘数值进行相加求和(因为是对存储在容器变量中的阶乘数值累加,所以需要遍历容器变量)即 for (int j = 0; j < r.size() ; j++):
① 将两个vector容器中的元素对应相加时需要注意的是,两个vector容器要能够相加需要大小一致,因此需要在大小较短的vector容器后面填充0,来保证它们的大小一致。
如果存储阶乘数值的容器r的大小比存储求和结果的容器 s 大,那么需要在容器的后面补0:
即 if (j == s.size()) s.push_back(0);
② 在相加的会有进位,因此,之前阶乘用到的存储进位和个位以上的数位的变量 还需要用到,可以将变量 c的作用域变大,让后面的语句块也可以识别到并使用。并且,如果遍历完整个容器 r 之后,还有进位,需要再进行一次运算,那么就需要在将之前遍历容器r的语句进行修改:for (int j = 0; j < r.size() || c; j++) 。a||b:只要其中一个不为0,结果就为1,需要继续执行语句。
③ 在第①步中已经考虑了“存储阶乘数值的容器r的大小比存储求和结果的容器 s 大”的情况,这一步需要考虑到“有进位c”的情况,此时容器r中被赋值(被初始化)的元素已经遍历完,后面的元素都未被初始化,元素值随机,因此,将容器 r 和容器 s中的元素一一对应相加时,需要给个判断,如果j<r.size(),此时,容器 r 中对应的元素被初始化过,可以写成:,如果j>r.size(),此时容器 r中对应的元素未被初始化,需要指定该元素的值为0,可以写成:,使用三元运算符将上面的两个代码整合在一起:
接着将结果赋值给一个整型变量 t
④ 通过上一步,得到两个容器的某一个数位相加的结果,之后将 变量 t 的个位放到存储求和结果的容器 s中,即 s[j] = t % 10;,接着让变量 c 存储数位在个位以上的数 c = t / 10;(因为是在循环里面,所以会一直运行到c==0 及 遍历完容器 r 为止,保证将数据都存储到容器s中) - 最后倒序输出容器 s中的元素就行。
三,代码
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin >> n;
vector<int> s(1, 0);
for (int i = 1; i <= n; i++)
{
vector<int> r(1, 1);
int c = 0;
for (int j = 1; j <= i; j++)
{
c=0;
for (int k = 0; k < r.size(); k++)
{
int t = r[k] * j + c;
r[k] = t % 10;
c = t / 10;
}
while (c)
{
r.push_back(c % 10);
c /= 10;
}
}
c = 0;
for (int j = 0; j < r.size() || c; j++)
{
if (j == s.size()) s.push_back(0);
int t = s[j] + (j < r.size() ? r[j] : 0) + c;
s[j] = t % 10;
c = t / 10;
}
}
for (int i = s.size() - 1; i >= 0; i--)
{
cout << s[i];
}
return 0;
}
有问题请在评论区留言或者是私信我,回复时间不超过一天。