[NOIP1998 普及组] 阶乘之和
题目描述
用高精度计算出 S = 1 ! + 2 ! + 3 ! + ⋯ + n ! S = 1! + 2! + 3! + \cdots + n! S=1!+2!+3!+⋯+n!( n ≤ 50 n \le 50 n≤50)。
其中 !
表示阶乘,定义为
n
!
=
n
×
(
n
−
1
)
×
(
n
−
2
)
×
⋯
×
1
n!=n\times (n-1)\times (n-2)\times \cdots \times 1
n!=n×(n−1)×(n−2)×⋯×1。例如,
5
!
=
5
×
4
×
3
×
2
×
1
=
120
5! = 5 \times 4 \times 3 \times 2 \times 1=120
5!=5×4×3×2×1=120。
输入格式
一个正整数 n n n。
输出格式
一个正整数 S S S,表示计算结果。
样例 #1
样例输入 #1
3
样例输出 #1
9
提示
【数据范围】
对于 100 % 100 \% 100% 的数据, 1 ≤ n ≤ 50 1 \le n \le 50 1≤n≤50。
【其他说明】
注,《深入浅出基础篇》中使用本题作为例题,但是其数据范围只有 n ≤ 20 n \le 20 n≤20,使用书中的代码无法通过本题。
如果希望通过本题,请继续学习第八章高精度的知识。
题解
高精度加法
void awithb(){ //求和;
memset(c,0,sizeof(c));
memset(d,0,sizeof(d));
memset(e,0,sizeof(e));
int sum1=strlen(sum);
int a1=strlen(a);
if(sum1==0){
strcpy(sum,a);
}
else{
for(int i=a1-1,j=0;i>=0;i--,j++){ //c=a;
c[j]=a[i]-'0';
}
for(int i=sum1-1,j=0;i>=0;i--,j++){
d[j]=sum[i]-'0';
}
int max=a1;
if(sum1>a1)max=sum1;
for(int i=0;i<=max;i++){
e[i]+=c[i]+d[i];
if(e[i]>=10){
e[i+1]++;
e[i]=e[i]%10;
}
}
memset(sum,'0',sizeof(sum));
int f=0,j,i;
if(e[max]!=0){
sum[0]=e[max]+'0';
f++;
}
for(i=max-1,j=f;i>=0;i--,j++){
sum[j]=e[i]+'0';
}
sum[j]='\0';
}
}
高精度乘法
1 0 9
* 9 9
————————
9 8 1
+ 9 8 1
——————————————
1 7 9 1
/*我们只要将他翻转过来;选择其中一位数,当另一个每进一位;
我们就将选定的那个数也进一位;
*/
for(z=0,k=0;z<max;z++,k++){
for(j=0,s=k;j<max;j++,s++){
e[s]+=c[z]*d[j];
if(e[s]>=10){
e[s+1]+=e[s]/10;
e[s]=e[s]%10;
}
}
}
高精度阶乘
for(int i=1;i<=n;i++){
memset(a,0,10000);
for(int j=1;j<=i;j++){
achenb(j);//求积;
}
awithb();//求和;
}
#include<bits/stdc++.h>
#include<cstring>
#include<cstdio>
using namespace std;
char a[10000],b[10000],sum[10000];
int c[10000],d[10000],e[10000];
void awithb(){ //求和;
memset(c,0,sizeof(c));
memset(d,0,sizeof(d));
memset(e,0,sizeof(e));
int sum1=strlen(sum);
int a1=strlen(a);
if(sum1==0){
strcpy(sum,a);
}
else{
for(int i=a1-1,j=0;i>=0;i--,j++){ //c=a;
c[j]=a[i]-'0';
}
for(int i=sum1-1,j=0;i>=0;i--,j++){
d[j]=sum[i]-'0';
}
int max=a1;
if(sum1>a1)max=sum1;
for(int i=0;i<=max;i++){
e[i]+=c[i]+d[i];
if(e[i]>=10){
e[i+1]++;
e[i]=e[i]%10;
}
}
memset(sum,'0',sizeof(sum));
int f=0,j,i;
if(e[max]!=0){
sum[0]=e[max]+'0';
f++;
}
for(i=max-1,j=f;i>=0;i--,j++){
sum[j]=e[i]+'0';
}
sum[j]='\0';
}
}
void achenb(int i){ //a=a*b;-->result=a;
memset(b,'0',sizeof(b));
memset(c,0,sizeof(c));
memset(d,0,sizeof(d));
memset(e,0,sizeof(e));
sprintf(b,"%d",i);
int a1=strlen(a);
int b1=strlen(b);
int sum=a1*b1;
if(a1==0){
a1=b1;
strcpy(a,b);
}
else{
int j,k,s,t,z;
for(z=a1-1,j=0;z>=0;z--,j++){
c[j]=a[z]-'0';
}
for(z=b1-1,j=0;z>=0;z--,j++){
d[j]=b[z]-'0';
}
int max=a1;
if(b1>a1)max=b1;
memset(a,0,sizeof(a));
for(z=0,k=0;z<max;z++,k++){
for(j=0,s=k;j<max;j++,s++){
e[s]+=c[z]*d[j];
if(e[s]>=10){
e[s+1]+=e[s]/10;
e[s]=e[s]%10;
}
}
}
sum++;
while(sum!=0){
if(e[sum]!=0)break;
sum--;
}
for(s=sum,t=0;s>=0;s--,t++){
a[t]=e[s]+'0';
}}
}
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
memset(a,0,10000);
for(int j=1;j<=i;j++){
achenb(j);//求积;
}
awithb();//求和;
}
for(int i=0;i<strlen(sum);i++){
printf("%c",sum[i]);
}
printf("\n");
return 0;
}