计算n的阶乘之和(高精度)


一、题目

计算 S = 1! + 2! + 3! + …… + n!( n <= 50)。
(注意数据范围)

输入格式
一个正整数 n。

输出格式
一个正整数 S,表示计算结果。

二、思路

刚开始看到这个题没看到要注意数据范围,直接用基础的递归算,当然直接wa了。
后面思考了一会,发现数据实在太大了,应该只能用高精度,只有这种算法才能够容纳这么大的数据。
所以,我们的思考重点自然也就转到怎么实现高精度的代码

求阶乘之和,自然是需要用到高精度乘法和高精度加法,要是对于这两个不熟悉,可以去看看这两个怎么实现的,简单地说就是小学的竖式算法,然后需要考虑前导0的问题即可

好了,现在我们都知道了需要用高精度加法和乘法,那应该怎么去协调这两个呢?
我们先一步一步来,先来实现高精度加法的代码

a数组是用来存每一个阶乘所对应的值,然后c就是要算到阶乘所对应的值
void add(int a[],int c)
{
	jw就是进位,假如这一位是3,那3 * 4 = 12,进位就是1,意思就是他的下一位就加 1
	int jw=0;
	//这里的1000是最大的n的阶乘所对应的最大的位数,我只是开了一个肯定超不了的数组
	for(int i=1;i<=1000;i++) 
	{
		a[i] = a[i] * c + jw;
		jw = a[i] / 10;
		a[i] = a[i] % 10; 
	}
}

但这个代码我当时是卡住了,不知道为什么能够这么写,后面慢慢理解了。
你想想,如果你算4的阶乘,那么就是4!=4*3*2*1 --> 4!=4*3! 就是这个c乘以c-1所对应的阶乘值,
然后反应在数组a的每一位中,让每一位都乘以c,
好了,现在我们实现了高精度乘法的部分,接下来就是高精度加法的部分了,那和上面没什么区别,思路一样的
void sum(int a[],int c[])
{
	int jw=0;
	for(int i=1;i<=1000;i++)
	{
		c[i] += a[i] + jw;
		jw = c[i] / 10;
		c[i] = c[i] % 10;
	}
}

三.完整代码

代码如下(示例):

#include <bits/stdc++.h>
using namespace std;

const int N = 1000;

typedef pair<int,int> PII;

int a[N],c[N];

void castal(int *a,int *c)
{
	int jw=0;
	for(int i=1;i<=1000;i++)
	{
		c[i]+=a[i]+jw;
		jw=c[i]/10;
		c[i]%=10;
	}
}


void sweet(int *a,int c)
{
	int jw=0;
	for(int i=1;i<=1000;i++)
	{
		a[i]=a[i]*c+jw;
		jw=a[i]/10;
		a[i]%=10;
	}
}

int main()
{
	int n,flag=0;
	cin>>n;
	a[1]=1;
	for(int i=1;i<=n;i++)
	{
		sweet(a,i);
		castal(a,c);	
	}
	
	for(int i=1000;i>0;i--)
	{
		if(c[i]!=0) flag=1;
		if(flag) cout<<c[i];
	}
	return 0;
}

2.读入数据

代码如下(示例):

3
9   

总结

总的来说这个题难度其实不高,只要理解了高精度的原理,就能够自己推出来,要是看了这篇文章还不是很懂的话,可以底下评论,我会来解答你的疑惑的,希望读者能从这篇文章中收获一些东西,谢谢查阅。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值