1. 程式人生 > >大數據處理N!(21<N<2000)

大數據處理N!(21<N<2000)

一位數 ron oot ostream 根據 strong main name 數學庫

輸入:

每行輸入1個正整數n,(0<n<1000 000)

輸出:

對於每個n,輸出n!的(十進制)位數 digit, 和最高位數firstNum。(n!約等於 firstNum * 10^[digit-1] )

方法一:

 利用數學庫及相關知識。

采用蠻力,根據定義,直接求解!

所謂n!的十進制位數,就是 log(n)+1, 根據數學公式有:n!=1*2*3*.....*n;

lg(n!)=lg(2)+......lg(n);

第一位數等於 pow(10, lg(n!)的小數部分)

 1 #include<iostream>
 2 #include<math.h>
 3 
 4 using namespace std;
 5 int main(){
 6 
 7         int N;
 8         cin>>N;
 9 
10         int firstNum=1; // should be 1-9
11         int digit=1;
12 
13         double num=0.0, yushu=0.0;
14 15 for(int i=2;i<=N;i++) 16 { 17 num=num+log10(i); 18 } 19 20 digit=(int)num + 1; 21 22 yushu = num + 1 - digit; 23 firstNum=pow(10,yushu); 24 25 cout<< firstNum<< " " <<digit<<endl;
26 27 28 }

方法二:

把所有數字以字符形式存於數組中,然後倒序輸出, 最關鍵點是要理解乘法的加法進位原理, 代碼和測試結果如下

 1 int main(){
 2 
 3 int N, digit=1,tmp=0,accu=0;
 4 cin>>N;
 5 
 6 int A[20000];
 7 
 8 A[0]=1;
 9 
10 for(int i=2;i<=N;i++)
11 {
12         accu=0;
13         tmp=0;
14         for(int j=0;j<digit;j++)
15         {
16                 tmp=A[j]*i+accu;
17                 A[j]=tmp%10;
18                 accu=tmp/10;
19         }
20         while(accu!=0){
21                 A[digit]=accu%10;
22                 accu/=10;
23                 digit++;
24         }
25 }
26 
27 digit--;
28 for(int i=digit; i>=0;i--)
29   cout<<A[i];
30 
31 cout<<endl;
32 
33 }

測試結果

[root@wl Geeks]# ./a.out
100
9332621544394415268169923885626670049071596826438162146859296389521759999322991

5608941463976156518286253697920827223758251185210916864000000000000000000000000

大數據處理N!(21<N<2000)