NYOJ 28.大數階乘(大數問題)
阿新 • • 發佈:2019-01-25
/*描述
我們都知道如何計算一個數的階乘,可是,如果這個數很大呢,我們該如何去計算它並輸出它?
輸入
輸入一個整數m(0<m<=5000)
輸出
輸出m的階乘,並在輸出結束之後輸入一個換行符
樣例輸入
50
樣例輸出
我們都知道如何計算一個數的階乘,可是,如果這個數很大呢,我們該如何去計算它並輸出它?
輸入
輸入一個整數m(0<m<=5000)
輸出
輸出m的階乘,並在輸出結束之後輸入一個換行符
樣例輸入
50
樣例輸出
30414093201713378043612608166064768844377641568960512000000000000
*/
對於大數問題,我們要有將大數與陣列結合的思想,可以利用類似於人工的方法求出有關大數的問題。
對於大數階乘來說,最重要的是如何將每個數的每位數與相對應的陣列元素儲存起來,就如算50的階乘,我們要先從1開始乘:
1*2=2,將2存到a[0]中,
2*3=6,將6儲存在a[0]中,
6*4=24,是兩位數,那麼24%10==4存到a[0]中,24/10==2存到a[1]中,
24*5=120,是三位數,那麼120%10==0存到a[0]中,120/10%10==2存到a[1]中,120/100==1存到a[2]中,
120*6=720,那麼720%10==0存到a[0]中,720/10%10==2存到a[1]中,720/100==7存到a[2]中,
...................
直到乘到50,將每一位數儲存為止。
#include <stdio.h> int main() { int carry,n,j; int a[40001];//儲存階乘的每一位數 int digit;//表示階乘的位數 int temp,i; scanf("%d",&n); a[0]=1; digit=1; for(i=2; i<=n; i++) { for(carry=0,j=1; j<=digit; ++j) { temp=a[j-1]*i+carry; a[j-1]=temp%10; carry=temp/10; } while(carry) { a[++digit-1]=carry%10; carry/=10; } } for(int k=digit; k>=1; --k)//倒序輸出每一位數 printf("%d",a[k-1]); printf("\n"); return 0; } /* #include <stdio.h> #include <string.h> #define MAX 20000 int main() { int arr[MAX]; memset(arr,0,sizeof(arr)); arr[0] = 1; int i,j,m,s; scanf("%d",&m); for(i=2;i<=m;i++) { int t = 0; for(j=0;j<MAX;j++) { s = arr[j] * i + t;//儲存計算的結果 arr[j] = s % 10;//把最低為存到陣列前面 t = s / 10;//計算進位 } } for(i=MAX-1;i>=0;i--)//把0都篩掉 { if(arr[i]) break; } for(j=i;j>=0;j--)//倒著輸出 { printf("%d",arr[j]); } printf("\n"); return 0; } */