题目
Given an integer N(0 ≤ N ≤ 10000), your task is to calculate N!
输入
One N in one line, process to the end of file.
输出
For each N, output N! in one line.
输入样例
1
2
3
输出样例
1
2
6
题目分析
此题就是求解10000以内的阶乘,但是稍稍一想,在C++中整数的范围也不过 2 31 ? 1 2^{31}-1 231?1,更大的long long int也不过是在此基础上的有限乘积。也有用double用于计算,但就最终的输出规模来看,这些已有的内置类型所能输出的范围完全不可能符合所有的输出条件。
由此可以思考改变策略,用自定义进制数组来完成结果的保留。
最初学习计算时,我们便知道在十进制乘法中,我们实质上是将每一位数与乘数相乘,然后对进制取余,同时存在进位。那么我们可以将在十进制乘法中的方法应用于更高位的进制中,比如说百进制,千进制,万进制等等。万变不离其宗,根本的计算思想是一致的。此题我采用了万进制的方法进行处理。
代码
#include<iostream>
#include<cstdio>
using namespace std;void fac(int n){
//计算阶乘int base[10005] ={
1};//数组中每一个元素均为万进制数,初始化第一个数为1,参与乘积int carry = 0,digit = 1;//carry————进位,digit————万进制的位数for(int i = 2;i<=n;++i){
carry = 0;//刷新进位for(int j = 0;j<digit;++j){
base[j]=base[j]*i+carry;//每一位乘以乘数并加上前一位乘积产生的进位carry = base[j] / 10000;//产生下一位进位base[j] %= 10000; }if(carry > 0)//是否最高位产生了进位base[digit++] = carry;}cout << base[digit-1];for(int i = digit -2;i >= 0;--i)printf("%04d",base[i]);//控制输出格式,对中间位数e.g897要输出0897cout << endl;return ;
}int main()
{
int n;while(scanf("%d",&n)!=EOF){
fac(n);}return 0;
}