大数相乘,大数相加。计算阶乘和

总时间限制:

1000ms

内存限制:

65536kB

描述

用高精度计算出S=1!+2!+3!+…+n!(n≤50)

其中“!”表示阶乘,例如:5!=5*4*3*2*1。

输入正整数N,输出计算结果S。

输入

一个正整数N。

输出

计算结果S。

样例输入

5

样例输出

153

思路:计算从 1!+2!+3! +~~~~ n!的和。

 如果n过大 则 n!是用 int 或者long 是存不下的 ,所以应该用高精度数乘低精度数,并存到数组里。

又因为你要计算从 1 到 n 的阶乘和 ,所以你要开一个二维数组,存下从1!到 n! 的阶乘数,

然后每一维相加。

上代码

#include<iostream>
#include<cstring>
using namespace std;
const int MAX = 50000;
int ans[52][MAX] , carry[MAX];
int Plus (int (*a)[MAX], int m, int n)
{
    	int i, k;
    	k = a[n][0] > a[m][0] ? a[n][0] : a[m][0];
    	for( i = 1;i <= k; i++)
    	{
    		a[n][i+1] += (a[n][i] + a[m][i]) / 10;
    		a[n][i] = (a[n][i] + a[m][i]) % 10; 	
    	}	
    	if(a[n][k+1] > 0)
    	a[n][0] = k+1;
    	else
    	a[n][0] = k;
    	return 0;
}
int main ()
{
	int n;
	cin >> n;
	for(int i = 1; i <= n; i++ )//初始化 二维数组 
	{
		ans[i][0] = 1; 	//一位数 
		ans[i][1] = 1;	//第一位是1; 
	}
	
	for (int k = 1; k <= n; k++)//计算从 1到 n的阶乘  
	{
		memset(carry, 0 ,sizeof(carry));
		for(int i = 1; i <= k; i++) //计算 k 的阶乘
		{
			for(int j = 1;j <= ans[k][0]; j++){
				ans[k][j] = ans[k][j] * i + carry[j];
				carry[j] = 0;
				if(ans[k][j] >= 10){
					carry[j+1] += ans[k][j]/10;
					ans[k][j] %= 10;
					if(j == ans[k][0]) ++ans[k][0];
					}
			}
		}
	}
	
	for(int i = 1; i < n; i++)
	{
		Plus(ans,i,n); //计算 从1到  n 的阶乘和, 
	}
	for(int i = ans[n][0]; i >= 1; i--)
	{
		cout << ans[n][i];
	} 
	
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/Harington/article/details/83510404