题目很简单,输入一个数n,求n的阶乘n!。
乍一看这道题真是简单,但是仔细一想当20!的时候,结果已经接近20位,哪怕是无符号的长整形,估计也放不了几个数,那么当这样的大数运算的时候应该怎么办了?
我们可以想一想,当我们在做乘法的时候是每一位相乘,然后低位进位,高位相加,最后得出结果,而对于每一位都是10以内的乘法,这就很简单了,所以在大数相乘中我们引入本位数组的概念(自己造的)和进位数组的概念。例如:
初始化本位数组f[n] 和进位数组add[0] ,分别赋初值为0;
5! =120,用本位数组表示就是f[1] = 0;f[2] = 2;f[3] = 1,当计算6!的时候f[1] = 0 * 6 = 0;f[2] = 2 * 6 = 12;f[3] = 1* 6 = 6,第二位也就是f[2]出现了需要进位的情况,
add[3] = f[2] / 10 = 1;
整理一下也就是6!如下计算:f[1] = (0 * 6 +add[1]) % 10 = 0;f[2] = (2 * 6 +add[2]) % 10 = 2;f[3] = (1 * 6 +add[3]) % 10 = 7;代码如下:
1 #include "stdafx.h" 2 #include <stdlib.h> 3 const int Max = 10001; 4 int _tmain(int argc, _TCHAR* argv[]) 5 { 6 int n,s,i; 7 //多组测试数据,以EOF结尾 8 while(scanf("%d",&n)!= EOF) 9 { 10 //初始化本位数组和进位数组,分别赋初值0 11 int num[Max] = {0}; 12 int add[Max] = {0}; 13 //赋初值1,从2开始计算,第一位没有进位 14 num[1] = 1; 15 add[1] = 0; 16 //定义一个数,代表当前位数 17 int m = 1; 18 scanf("%d",&n); 19 //从2开始阶乘计算 20 for(s = 2;s <= n;s++) 21 { 22 //循环当前数的位数,分别计算每一位的本位数和进位数 23 for(i = 1;i <= m ;i++) 24 { 25 //这两行是核心代码,根据上面的解释看懂不是问题 26 add[i + 1] = (num[i] * s + add[i]) / 10; 27 num[i] = (num[i] * s + add[i]) % 10; 28 //当当前数的最高位有进位时,循环位数+1 29 if(add[i + 1] > 0 && i == m) 30 m++; 31 }35 } 36 for(i = m;i >= 1;i--) 37 { 38 printf("%d",num[i]); 39 } 40 } 41 system("Pause"); 42 return 0; 43 }