题目描述
用高精度计算出S=1!+2!+3!+…+n! (n≤50)S=1!+2!+3!+…+n!(n≤50)
其中“!”表示阶乘,例如:5!=5 *4 *3 * 2
15!=5×4×3×2×1。
输入格式
一个正整数N
输出格式
一个正整数S,表示计算结果。
输入输出样例
输入
3
输出
9
说明/提示
注,《深入浅出基础篇》中使用本题作为例题,但是其数据范围只有 n≤20,使用书中的代码无法通过本题。
如果希望通过本题,请继续学习第八章高精度的知识。
错误代码:
#include <iostream>
#include <cstring>
using namespace std;
#define Max 100000000
int Jieceng(int N,int* nums)
{
int k;//标记位数
int n = 0;//标记进位
for(int i=1;i<=n;i++)
{
for(int j=1;j<=k;j++)
{
nums[j] = nums[j]*i+n;
n = nums[j]/10;
nums[j] = nums[j]%10;
}
while(n!=0)
{
n = n%10;
nums[k] += n;
n = n/10;
k++;
}
}
return k;
}
int Sum(int* nums,int* nums1,int N)
{
int n = 0;
for(int i=1;i<=N;i++)
{
nums[i]=nums[i]+nums1[i]+n;
n = nums[i]/10;
nums[i] = nums[i]%10;
}
while(n!=0)
{
n = n%10;
nums[N+1] +=n;
n = n/10;
N++;
}
return N;
}
int main()
{
int N;
cin>>N;
int nums[Max];
int sum[Max];
memset(sum,0,sizeof(int)*Max);
memset(nums,0,sizeof(int)*Max);
nums[0] = 1;
int k;
int m;
for(int i=1;i<=N;i++)
{
k = Jieceng(i,nums);
m = Sum(sum,nums,k);
}
for(int i=m;i<=1;i--)
{
cout<<sum[i];
}
}
问题分析
- 此算法很慢并且在DevC++上运行不了,暂时没有发现原因,但大佬的代码更加简单,将数组接着上一次的数字相乘,并且设置标记变量这样就不用设置位数
- 数组作为全局变量声明的话,就不需要返回值
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
int a[2000];
//int b[2000];
int c[2000];
//int sum[2000];
void JieCeng(int* a,int m)
{
int n=0;//进位
for(int i =1;i<=1000;i++)
{
a[i] = a[i]*m+n;//第一次
n = a[i]/10;
a[i]%=10;
}
}
void Plus(int* a,int* c)
{
//用一个数组储存相加的值,每次阶乘完立马相加
int n = 0;
for(int i=1;i<=1000;i++)
{
c[i] = a[i]+c[i]+n;
n = c[i]/10;
c[i] = c[i]%10;
}
}
int main()
{
int N;
cin>>N;
a[1] = 1;
for(int i=1;i<=N;i++)
{
JieCeng(a,i);
Plus(a,c);
}
bool flag = 0;
for(int i=1000;i>0;i--)
{
if(c[i]!=0)
{
flag = 1;//当遇到最高位时,flag变为1,这样就知道是否到了最高位
}
if(flag==1)
{
cout<<c[i];
}
}
}
参考别人答案写出来的代码
总结
- 全局变量的运用
- 标记变量的运用
- 数组是需要返回值的
- 阶乘是乘完了再加进位,不能先加进位再相乘,如果累加是允许先加进位的