首先,题目传送门是一定要有的 接下来就是题目描述了
题目描述
用高精度计算出S=1!+2!+3!+…+n! (n≤50) 其中“!”表示阶乘,例如:5!=5×4×3×2×1。
输入格式
一个正整数N。
输出格式
一个正整数S,表示计算结果。
输入输出样例
输入 #1
3
输出 #1
9
说明/提示
注:《深入浅出基础篇》中使用本题作为例题,但是其数据范围只有 n<=20,使用书中的代码无法通过本题。 如果希望通过本题,请继续学习第八章高精度的知识。
好了,题目看完了,首先肯定要定义变量对吧,因为考虑到1!+2!+3!+…+50!可能会很大,所以定义的变量要尽可能地大,因为题目限制内存在125MB之内,所以int类型的数组最大的长度为125MB/4B=32768000考虑到后面还会有变量,故把数组长度设置为3276800接下来就是高精度阶乘和高精度加法,如果你学习过高精度,接下来的部分你可以掠过,没有学习过的可以看一下加粗部分的字
首先是高精度加法,其实就是循环把每一位都加起来,比如42954+69837,计算过程如下: 4+7=11,11>=10,所以进位就是1,这一位就变成了1; 3+5+1=9,9<10,所以进位就是0,这一位就还是9; 8+9=17,17>=10,所以进位就是1,这一位就变成了7; 2+9+1=12,12>=10,所以进位就是1,这一位就变成了2; 4+6+1=11,11>=10,所以进位就是1,这一位就变成了1; 所以最后的结果为112791 乘法也一样,只不过多了些进位而已,知道了这些,就可以做高精度阶乘了. 接下来,上代码!
源代码
#include <cstdio>
#include <iostream>
#include <cstring>
#include <climits>
using namespace std
;
int fac
[16328],sum
[16328]={0};
int nmax
=INT_MIN
;
int factorial(int n
){
fac
[1]=1;
int mul
=1,len
=1;
while(n
--){
int carry
=0;
for(int i
=1;i
<=len
;i
++){
fac
[i
]=fac
[i
]*mul
+carry
;
carry
=fac
[i
]/10;
fac
[i
]=fac
[i
]%10;
}
mul
++;
while(carry
){
fac
[++len
]=carry
%10;
carry
/=10;
}
}
return len
;
}
int main(){
int n
,tmptmp
=0;
cin
>>n
;
for(int i
=1;i
<=n
;i
++){
int tmp
=factorial(i
);
if(tmp
>nmax
) nmax
=tmp
;
for(int j
=1;j
<=tmp
;j
++){
sum
[j
]+=fac
[j
];
sum
[j
]+=tmptmp
;
if(sum
[j
]>=10){
tmptmp
=1;
sum
[j
]-=10;
}else tmptmp
=0;
}
}
for(int i
=nmax
;i
>=1;i
--) cout
<<sum
[i
];
return 0;
}