题目描述
用高精度计算出 S=1!+2!+3!+⋯+n!(n≤50)。
其中“!”表示阶乘,例如:5!=5×4×3×2×1。
输入格式
一个正整数 n。
输出格式
一个正整数 S,表示计算结果。
输入输出样例
输入:3
输出:9
说明/提示
【数据范围】
对于100% 的数据,1≤n≤50。
【其他说明】
注,《深入浅出基础篇》中使用本题作为例题,但是其数据范围只有 n≤20,使用书中的代码无法通过本题。
如果希望通过本题,请继续学习第八章高精度的知识。
解题思路:
这是一道高精度的题,n的最大值达到了50,即使用unsigned long long 数据类型也会超出范围,因此需要模拟手写计算过程,如果不理解的话可以自己动手算一算。使用两个数组分别记录当前的阶乘数值和相加之后得到的数值,数组中的每个元素只用来记录一个数字,连在一起才是阶乘或相加之后的数值。
AC代码:
#include <bits/stdc++.h>
using namespace std;
int a[1000];//存储阶乘得到的每一位数
int b[1000];//存储当前相加和得到的每一位数
int main()
{
int n;
cin>>n;
for(int i=0;i<1000;i++)
{
a[i]=b[i]=0;
}
a[1]=1;
for(int i=1;i<=n;i++)
{
int temp=0;
for(int j=1;j<=1000;j++)//模拟手写乘法,注意进位
{
a[j]=a[j]*i+temp;
temp=a[j]/10;
a[j]=a[j]%10;
}
temp=0;
for(int j=1;j<=1000;j++)//模拟手写加法,注意进位
{
b[j]=b[j]+a[j]+temp;
temp=b[j]/10;
b[j]=b[j]%10;
}
}
int k;
for(int i=999;i>=0;i--)//因为最高位不可能为0,所以从后往前找到第一个不为0的数
{
if(b[i]!=0)
{
k=i;break;
}
}
for(int i=k;i>=1;i--)//从后往前输出,直到i为1
{
cout<<b[i];
}
return 0;
}