资源限制
时间限制:1.0s 内存限制:512.0MB
问题描述
输入一个正整数n,输出n!的值。
其中n!=123*…*n。
算法描述
n!可能很大,而计算机能表示的整数范围有限,需要使用高精度计算的方法。使用一个数组A来表示一个大整数a,A[0]表示a的个位,A[1]表示a的十位,依次类推。
将a乘以一个整数k变为将数组A的每一个元素都乘以k,请注意处理相应的进位。
首先将a设为1,然后乘2,乘3,当乘到n时,即得到了n!的值。
输入格式
输入包含一个正整数n,n<=1000。
输出格式
输出n!的准确值。
样例输入
10
样例输出
3628800
#include <bits/stdc++.h>
using namespace std;
int c;
int main()
{
int n,ji,jinwei=0;
vector<int> A(10000,0); //用vector来生成数组,并初始化
cin>>n;
A[0]=1; //将数组第一个值赋为1
for(int i=2;i<=n;i++) //要乘的数,从1开始不断往上乘,一直乘到n
{
for(int j=0;j<A.size();j++) //外层循环每增加一个数,数组都要遍历一遍,更新数组,因为不确定阶乘的最终位数,所以数组的每一个数都要遍历
{
ji=A[j]*i+jinwei; //jinwei是来自上一位(A[j-1])的进位,A[j]*i+jinwei是本次循环A[j]的实际值,由ji暂存,进入下面if语句进行判断
if(ji>=10) //大于10要向下一位(A[j+1])产生进位
{
A[j]=ji%10; //取ji的个位数作为A[j]的实际值
jinwei=ji/10; //产生向下一位的进位
}
else //小于10不用产生进位
{
A[j]=ji; //ji的值即为A[j]的值
jinwei=0; //这步很重要,不产生进位,进位记得要清零,以免影响对下一位的运算
}
}
}
reverse(A.begin(),A.end()); //将数组元素翻转,逆序排列
//逆序后会产生类似“00000000035223052”这样的数,前面的0是没有用到的位数,后面的数是实际阶乘值,将前面的0去掉即可
for(int k=0;k<A.size();k++) //遍历寻找第一个不为0的元素的下标
{
if(A[k]!=0)
{
c=k; //将下标k赋给全局变量c
break;
}
}
for(int m=c;m<A.size();m++) //这里不将k直接赋值给m是因为k是上边那层循环的,带不到这来,所以用个中间变量过度一下
{
cout<<A[m];
}
return 0;
}