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;
}