解题思路:


                看了好多题解,基本都是一样的。每一个都是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;
}


点赞(11)
 

0.0分

11 人评分

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 3 条评论

陈彦庭 2年前 回复TA
如果前一位相乘是百位,那num又是如何相加的
煮酒老麦 4年前 回复TA
可是这个解法也定义了一个a[20001]啊。
华农赵子龙 5年前 回复TA
大数算法的基本思路应该就是如作者所说的那样子了吧,想了一下,有关大数不仅仅是加,减乘除都可以用类似的格式来运算呀,算是长见识了哈哈哈哈