1105: 求N的阶乘
时间限制: 3 Sec 内存限制: 65536 MB提交: 11 解决: 3
[ 提交][ 状态][ 讨论版]
题目描述
我们都知道如何计算一个数的阶乘,可是,如果这个数很大呢,我们该如何去计算它并输出它?
输入
输入文件第一行有一个整数n(1≤n≤50),以下n行每行有个整数k(0<k<5000)。
输出
输出文件有n行,各包含一个结果。
样例输入
2
5
50
样例输出
120
30414093201713378043612608166064768844377641568960512000000000000
提示
解题思路:肯定不能按不同的方法求解;
这是一个大数问题:
我们模拟下乘法运算:
例:192*9;
2*9=18;把8留在个位,1向前进位
9*9=81;把1留在十位,8向前进位
1*9=9;把9留在百位
一个数m与个位数n相乘,是不是把每个m的位数值乘与n所得数值的个位留在当前位,十位进位。
例:51*50;
1*50=50;把0留在个位,5向前进位
5*50=250;把0留在十位,5向前进位,2向前进两位
一个数m与一个数n相乘,是不是把每个m的位数值乘与n所得数值的个位留在当前位,十位进位,百位进两位.....。
明白这些就能解决这个问题。
我们利用数组【0】代表个位,【1】代表十位,【2】代表百位......。
#include<cstdio>
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,k=0;
int num[1005]={0};
num[0]=1;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
for(int j=0;j<=k;j++)
{
num[j]=num[j]*i;
}
for(int j=0;j<=k;j++)
{
if(num[j]>=100)
{
num[j+2]+=num[j]/100;
num[j+1]+=(num[j]-num[j]/100*100)/10;
num[j]=num[j]%10;
}
if(num[j]>=10)
{
num[j+1]+=num[j]/10;
num[j]=num[j]%10;
}
}
if(num[k+2]!=0) k=k+2;
else if(num[k+1]!=0) k++;
}
for(int i=k+1;i>=0;i--)
printf("%d",num[i]);
printf("\n");
}
return 0;
}
下边是优化过的代码可以解决任意为的阶乘(上边的代码只能解决到100以下的阶乘):
源代码:
#include<cstdio>
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,k=0;
int num[100005]={0};
num[0]=1;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
for(int j=0;j<=k;j++)
{
num[j]=num[j]*i;
}
int l=0;//两个功能,测量增加位数,和进位
for(int j=0;j<=k;j++)
{
if(num[j]>=10)
{
int s=num[j];
num[j]=0;
l=j;//进位
while(s)
{
num[l++]+=s%10;
s=s/10;
}
}
}
while(l--)//增加位数
{
if(num[k+l]!=0)
{
k=k+l;
break;
}
}
}
for(int i=k;i>=0;i--)
printf("%d",num[i]);
printf("\n");
}
return 0;
}