题解:
题目难度:中等难度
难点:
1.由于数据太大无法通过整数类型表示,因此用字符串存储结果
2.对于每个字符串从尾部开始进行简单的乘法,在其中考虑进位
知识点:大数相乘
思路:
1.构造multiply(int x, int res[], int res_size)函数,数组res存储被乘数,res_size为被乘数的位数,x为乘数,该函数将两者乘积结果放入数组res(res重新赋值为两者的乘积),该函数返回数组乘积结果的长度。比如10!=3628800已经存储到数组res中,此时res_size=7,计算11!=10! * 11过程如下:
步骤一:
从数组res下标0处开始,依次乘上11,如res[i]11,因为十进制数,考虑向前进位,所以此时res[i]=(res[i]11)%10,向前进位carry = (res[i]*11)/10。按这种方式从下标0计算到下标res_size-1。
步骤二:
需要计算最高为res[res_size-1]所产生的进位。此时产生的进位carry=(res[res_size-1]*11)/10。此时使用while循环判断carry时几位数,把该数从低位开始依次存入res[res_size++]中。
那么调用multiply( 11, int res[], 7)
2.计算n!相当于计算1!2=2!,2!3=3!,3!*4=4!,依次类推下去。因此,利用for循环,i从1到n,在其中依次调用multiply(i, res[], res_size),最终n!的结果保存在数组res中,从高位到低位依次输出即可。
#include <iostream> using namespace std; // 数组e799bee5baa6e58685e5aeb931333361326235乘法, res_size: 表示有多少位, 返回结果的位数 int multiply(int x, int res[], int res_size) { int carry = 0; // 进位 for (int i=0; i<res_size; i++) { int prod = res[i] * x + carry; res[i] = prod % 10; carry = prod/10; } while (carry!=0) { res[res_size] = carry%10; carry = carry/10; res_size++; } return res_size; } void factorial(int n) { int res[36000]; // 10000! 位数不超过36000 // 初始化 res[0] = 1; int res_size = 1; // 表示有多少位 // 计算 n! for (int x=2; x<=n; x++) { res_size = multiply(x, res, res_size); } for (int i=res_size-1; i>=0; i--) { cout<<res[i]; } } int main() { int n; cin>>n; factorial(n); }