数的长度
原题链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=69
分析:先看看求n!的朴素算法,用大整数乘法来实现。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 int wei[1000000]; 6 int main() 7 { 8 int t,n; 9 scanf("%d",&t); 10 while(t--) 11 { 12 memset(wei,0,sizeof(wei)); 13 int cnt=0; 14 scanf("%d",&n); 15 wei[cnt]=1; 16 for(int i=1;i<=n;i++) 17 { 18 int carry=0; 19 for(int j=0;j<=cnt;j++) 20 { 21 int t=carry; 22 carry=(wei[j]*i+t)/10; 23 wei[j]=(wei[j]*i+t)%10; 24 } 25 if(carry) 26 { 27 wei[++cnt]=carry; 28 wei[cnt]=carry%10; 29 carry/=10; 30 } 31 while(carry>=10) 32 { 33 wei[++cnt]=carry%10; 34 carry/=10; 35 } 36 if(carry) 37 wei[++cnt]=carry; 38 } 39 printf("%d ",cnt+1); 40 } 41 return 0; 42 }
分析:设n!=10^M,则log10(n!)=M=log10(1)+log10(2)+……,然后向上取整即可!
也可以直接套公式!n!的位数 = log10(2*PI*n)/2+n*log10(n/e)。或者 = log10(sqrt(2*PI*n)) + n*log10(n/e)。
stirling公式证明: http://episte.math.ntu.edu.tw/articles/mm/mm_17_2_05/index.html
附:PI=acos(-1.0)=2acos(0.0).
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 using namespace std; 6 int fac[1000005]; 7 void wei(int n) 8 { 9 double M=0; 10 fac[0]=1; 11 fac[1]=1; 12 for(int i=2;i<=n;i++) 13 { 14 M+=log10(i); 15 if(M-(int)M!=0) 16 fac[i]=(int)M+1; 17 else 18 fac[i]=(int)M; 19 } 20 } 21 int main() 22 { 23 wei(1000000); 24 int t,n; 25 scanf("%d",&t); 26 while(t--) 27 { 28 scanf("%d",&n); 29 printf("%d ",fac[n]); 30 } 31 return 0; 32 }
1 2 #include<iostream> 3 #include<cstdio> 4 #include<cstring> 5 #include<cmath> 6 #define pi acos(-1.0) 7 using namespace std; 8 int main() 9 { 10 int t,n; 11 scanf("%d",&t); 12 while(t--) 13 { 14 scanf("%d",&n); 15 double ans=(log10(2*pi*n))/2+n*log10(n/exp(1.0)); 16 printf("%d ",(int)ans+1); 17 } 18 return 0; 19 } 20