咖啡


私信TA

用户名:Tianxn

访问量:138171

签 名:

十年OI一场空,不开LL见祖宗。

等  级
排  名 10
经  验 27303
参赛次数 10
文章发表 197
年  龄 22
在职情况 学生
学  校 西安电子科技大学
专  业 软件工程

  自我简介:

解题思路:


                看了好多题解,基本都是一样的。每一个都是5000多少位来着,忘了;但是有必要一定知道结果是多少位吗????!!!!


对于大数来说,一个数的阶乘是非常大的,同样,一个int类型的整数,他的阶乘就有可能会很大。

就拿50来说,他的阶乘位数是65位,就已经远远超过了long long int类型的最大值。这时候,我们要通过字符串的方法,来进行阶乘的运算。

当然,需要注意的是:

我们所求一个数的阶乘,这个数是在int范围内的,5000的阶乘位数是16326位。

其方法是:

首先,我们是可以先求一定范围内的最大值的阶乘位数,以便于申请数组空间的确定。


对于大数问题,我们要有将大数与数组结合的思想,可以利用类似于人工求值的方法求出有关大数的问题。

对于大数阶乘来说,最重要的是如何将每个数的每位数与相对应的数组元素储存起来,就如算50的阶乘,我们要先从1开始乘:

1*2=2,将2存到a[0]中,

接下来是用a[0]*3;

    2*3=6,将6储存在a[0]中,

接下来是用a[0]*4;

    6*4=24,是两位数,那么24%10==4存到a[0]中,24/10==2存到a[1]中,

接下来是用a[0]*5;a[1]*5+num(如果前一位相乘结果位数是两位数,那么num就等于十位上的那个数字;如果是一位数,num==0)

    24*5=120,是三位数,那么120%10==0存到a[0]中,120/10%10==2存到a[1]中,120/100==1存到a[2]中,

接下来是用a[0]*6;a[1]*6+num;a[2]*6+num;

    120*6=720,那么720%10==0存到a[0]中,720/10%10==2存到a[1]中,720/100==7存到a[2]中,

...................

直到乘到50,将每一位数储存为止。



注意事项:

参考代码:

#include <stdio.h>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <functional>
using namespace std;
const int maxn = 20001;
int a[maxn];
int main()
{
	int k, digit = 1, n;           // digit是结果的位数
	a[0] = 1;
	//scanf("%d", &n);
	n = 1977;
	for(int i = 2; i <= n; ++i)
	{
		k = 0;
		for(int j = 0; j < digit; ++j)
		{
			int temp = a[j]*i + k;
			a[j] = temp%10;
			k = temp/10;
		}
		while(k)
		{
			a[digit] = k%10;
			k /= 10;
			digit++;
		}
	}
	for(int i = digit-1; i >= 0; --i)
	{
		printf("%d", a[i]);
	}
	printf("\n"); 
	return 0;
}


 

0.0分

14 人评分

  评论区

如果前一位相乘是百位,那num又是如何相加的
2022-11-09 12:00:08
可是这个解法也定义了一个a[20001]啊。
2020-03-05 20:02:21
大数算法的基本思路应该就是如作者所说的那样子了吧,想了一下,有关大数不仅仅是加,减乘除都可以用类似的格式来运算呀,算是长见识了哈哈哈哈
2019-04-24 09:01:18
  • «
  • 1
  • »