洛谷p1009,阶乘求和

题目描述

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

其中 ! 表示阶乘,定义为 n!=n×(n−1)×(n−2)×⋯×1n!=n×(n−1)×(n−2)×⋯×1。例如,5!=5×4×3×2×1=1205!=5×4×3×2×1=120。

输入格式

一个正整数 nn。

输出格式

一个正整数 SS,表示计算结果。

输入输出样例

输入 #1

3

输出 #1

9

题目分析:

        思路:

                        大致推断,50的阶乘已经非常大,更不用说求和,因此精度肯定不够,所以要利用高精度思想

        1.外循环完成高精度求和,内循环要完成高精度乘积,如何将每一个数字放进用来做高精度的数组,此处介绍一种方法,进行乘法运算,两个乘数,用一个数乘另一个数的每一位,最后进行进位,如图

        洛谷p1009,阶乘求和_第1张图片

 所以循环里面就可以直接每次给每一位乘循环数,记得每次成完,要进行进位,也就是

    for (j=0; j<100; j++) {//进行乘法之后进位 
			if (B[j]>9) {
				B[j+1] += B[j]/10;
				B[j]%=10; 
			}
		}

求和之后也要注意进位,最后输出的时候,也要注意位数,注意因为乘法和减法要求对齐,所以数组里面的数字是反着的,借此达到对齐的想法。

代码:

        

#include
/*
此处注释为了解释: for (j=0; j<100; j++) {		这段代码是在干嘛 
					B[j]*=i;
					}
	计算多位数的乘法,利用分配律,比如123*13
	将123分为100,20,3,直接用13*1,13*2,13*3,得到13|26|39,然后进位,原本的位置留下x/10,进位x%10,
	13|29|9,15|9|9,最终答案就是 1599,所以,而每次给数组每一个元素*i。
	其实就是乘法,但是这样做之后就会非常巧妙 !!! 
*/
int main() {
	int i,A[1005]= {0},B[1005]= {0},n,j;
	scanf("%d", &n);
	A[0]=B[0]=1;
	for (i=2; i<=n; i++) {
		for (j=0; j<100; j++) {//看上面注释 
			B[j]*=i;
		}
		for (j=0; j<100; j++) {//进行乘法之后进位 
			if (B[j]>9) {
				B[j+1] += B[j]/10;
				B[j]%=10; 
			}
		}
		for (j=0; j<100; j++) {//进行加法进位 
			A[j]+=B[j];
			if (A[j]>9) {
				A[j+1] += A[j]/10;
				A[j]%=10;
			}
		}
	}
	for (i=100; ; i--) {
		if(A[i]>0&&i>=0) {
			break;
		}
	}
	for (j=i; j>=0; j--) {
		printf("%d", A[j]);
	}
	return 0;
}

        本身比较简单,主要是关于求出乘积,其实也可以,第一次将数字赋给数组,然后每次用数组和第几个数字的  i  做乘积,

你可能感兴趣的:(做题,算法)