15:阶乘和
查看提交统计提问
总时间限制: 1000ms 内存限制: 65536kB
描述
用高精度计算出S=1!+2!+3!+…+n!(n≤50)
其中“!”表示阶乘,例如:5!=54321。
输入正整数N,输出计算结果S。
输入
一个正整数N。
输出
计算结果S。
样例输入
5
样例输出
153
该问题需要将大数阶乘问题与大数累加问题结合起来
我分出了两个函数来解决
每个函数的时间复杂度应该是O(n^2) 不知道有没有大佬优化一下
以下为参考代码 注释很多 应该不需要格外补充说明
#include <iostream>
#include <algorithm>
#include <string.h>
#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;
}