15:阶乘和
查看提交统计提问
总时间限制: 1000ms 内存限制: 65536kB
描述
用高精度计算出S=1!+2!+3!+…+n!(n≤50)
其中“!”表示阶乘,例如:5!=54321。
输入正整数N,输出计算结果S。
输入
一个正整数N。
输出
计算结果S。
样例输入
5
样例输出
153
该问题需要将大数阶乘问题与大数累加问题结合起来
我分出了两个函数来解决
每个函数的时间复杂度应该是O(n^2) 不知道有没有大佬优化一下
以下为参考代码 注释很多 应该不需要格外补充说明
#include#include #include #define MAX 3600 using namespace std; int N; int k; int fac[MAX]; //每次的阶乘 int add[MAX]; //阶乘之和 int addition(int n); //函数声明 int factorial(int n); //函数声明 int main() { cin >> N; //接入n addition(N); //发送n for(int i = k;i >= 1;i--) { cout << add[i]; //遍历输出 } return 0; } int addition(int n) { int x = 0; memset(add,0,sizeof(add)); //置零求和数组 for(int i = 1;i <= n;i++) { k = factorial(i); //分别求1 2 3 .... n的阶乘 并取出阶乘的位数 for(int j = 1;j <= k;j++) { add[j] += fac[j] + x; //累加 x = add[j] / 10; //位数 add[j] = add[j] % 10; //求余数 if(x != 0 && j == k) //进位不为0且当前为数为最大位数 { k++; //进位 } } } return 0; } int factorial(int n) //n的阶乘 { int x,k1; //进位 当前位数 k1 = 1; //1! = 1 占一位 memset(fac,0,sizeof(fac)); //每次将阶乘值置零 fac[1] = 1; //在第一位上开始累计 for(int i = 1;i <= n;i++) // *n 次 { x = 0; //进位默认置零 for(int j = 1;j <= k1;j++) //相乘限定在k位 { fac[j] = fac[j] * i + x;//只要不超过k位 就每一位都进行相乘 并且加x 逢十进一 x = fac[j] / 10; //逢十进一 fac[j] = fac[j] % 10; //只保留最后一位 if(x != 0 && j == k1) //如果x有进位并且当前位数与最大位数相当 { k1++; //最大位数+1 } } } return k1; }



