题型介绍
有这么一类题目,要求求解n以内的阶乘,由于最终结果往往非常巨大,不能用常用的数据类型来保存,这时候我们便可以选择使用数组来保存这样的大整数。
求阶乘的过程中,每次乘法运算可以视为一个大整数与一个普通整数相乘,那么我们便可以让这一个普通整数依次与大整数的每一位相乘,同时注意处理好进位关系。
记忆要点:数组保存大整数、大整数与普通整数相乘
核心代码:
int num[maxn+1];
num[1] = 1; //这里我们从数组的1号下标开始使用
int len = 1;//len用于保存结果的位数
int carry = 0;//保存进位
for (int i = 2; i <= n; i++) {//求n的阶乘
for (int j = 1; j <= len; j++) {
int tmp = i*num[j] + carry;//注意此处进位不参与乘法运算
num[j] = tmp % 10;
carry = tmp / 10;
}
while (carry > 0) {//处理普通整数与大数最高位相乘之后的进位
num[++len] = carry % 10;//这里大数的长度就增长了
carry /= 10;
}
}
下面来看两道例题:
例题1 求1000以内N的阶乘
输入一个正整数N,输出N的阶乘。
输入描述:
正整数N(0<=N<=1000)
输出描述:
输入可能包括多组数据,对于每一组输入数据,输出N的阶乘
示例1
输入
4
5
15
输出
24
120
1307674368000
AC代码:
#include<iostream>
using namespace std;
int num[3001];//使用数组存放大数 3000位对于100以内的阶乘足够了
int main() {
int n;
while (cin >> n) {
for (int i = 1; i <= 3000; i++) {
num[i] = 0;
}
num[1] = 1; int len = 1;//len用于保存结果的位数
int carry = 0;
for (int i = 2; i <= n; i++) {
for (int j = 1; j <= len; j++) {
int tmp = i*num[j] + carry;
num[j] = tmp % 10;
carry = tmp / 10;
}
while (carry > 0) {
num[++len] = carry % 10;
carry /= 10;
}
}
for (int i = len; i > 0; i--) {
cout << num[i];
}
cout << endl;
}
}
例题2 求10000以内N的阶乘
求10000以内n的阶乘。
Input
只有一行输入,整数n(0<=n<=10000)。
Output
一行,即n!的值。
Sample Input
100
Sample Output
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
与上一题没有什么大的差别,将数组开大即可。
AC代码:
#include<iostream>
using namespace std;
int num[300001];
int main() {
int n;
cin >> n;
for (int i = 1; i <= 300000; i++) {
num[i] = 0;
}
num[1] = 1; int len = 1;//len用于保存结果的位数
int carry = 0;
for (int i = 2; i <= n; i++) {
for (int j = 1; j <= len; j++) {
int tmp = i*num[j] + carry;
num[j] = tmp % 10;
carry = tmp / 10;
}
while (carry > 0) {
num[++len] = carry % 10;
carry /= 10;
}
}
for (int i = len; i > 0; i--) {
cout << num[i];
}
cout << endl;
//system("pause");
}