斯特林公式

斯特林公式是一条用来取n阶乘近似值的数学公式。一般来说,当n很大的时候,n阶乘的计算量十分大,所以斯特灵公式十分好用。

斯特林公式可以用来估算某数的大小,结合lg可以估算某数的位数,或者可以估算某数的阶乘是另一个数的倍数。
Stirling公式的意义在于:当n足够大时,n!计算起来十分困难,虽然有很多关于n!的等式,但并不能很好地对阶乘结果进行估计,尤其是n很大之后,误差将会非常大。但利用Stirling公式可以将阶乘转化成幂函数,使得阶乘的结果得以更好的估计。而且n越大,估计得越准确。

斯特林公式(Stirling's approximation)是一条用来取n的阶乘近似值的数学公式。一般来说,当n很大的时候,n阶乘的计算量十分大,所以斯特林公式十分好用,而且,即使在n很小的时候,斯特林公式的取值已经十分准确。求N!的位数:
lnN!=NlnN-N+0.5*ln(2*N*pi)  !

要想求有多少位,将他换成以10为底便可。

利用换底公式得  lnN!/ln10=log10N!把式子取整形加1就是位数!

第一个题,求阶乘的最高位。

http://acm.cs.ecnu.edu.cn/problem.php?problemid=1007

不用说,肯定是用斯特林公式,不过要注意前面1~9还是自己打个表吧,很简单的。

代码:


 
 
  1. #include<stdio.h>
  2. #include<math.h>
  3. #include<stdlib.h>
  4. #define e 2.71828182845
  5. #define pi 3.1415926
  6. int main()
  7. {
  8. long a ;
  9. double s ;
  10. int result = 0 ;
  11. while( scanf( "%d", &a ) != EOF )
  12. {
  13. if ( a > 3 && a != 7 && a != 8 )
  14. {
  15. s = 0.5 * log10 ( 2 * pi * a ) + a * ( log10 ( a ) - log10(e) ) ;
  16. s = s - ( int ) s ;
  17. result = ( int ) pow ( 10 , s ) ;
  18. printf( "%d\n",result ) ;
  19. continue ;
  20. }
  21. if ( a <= 1 ) { printf( "1\n"); continue ;}
  22. if ( a == 2 ) { printf( "2\n" ) ; continue ; }
  23. if ( a == 3 ) { printf( "6\n" ) ; continue ;}
  24. if ( a == 7 ) { printf( "5\n"); continue ; }
  25. if ( a == 8 ) { printf( "4\n" ) ; continue ; }
  26. }
  27. }

第二题:判断阶乘的位数。

http://poj.org/problem?id=1423

代码:


 
 
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #include<math.h>
  5. const double e = 2.71828182845;
  6. const double pi = 3.1415926;
  7. int main(void)
  8. {
  9. int t, i, f, v;
  10. double a, s;
  11. const double log10_e = log10(e);
  12. const double log10_2_pi = log10( 2.0*pi)/ 2.0;
  13. while ( scanf( "%d", &t) != EOF && t)
  14. {
  15. for (i = 0; i < t; ++i)
  16. {
  17. scanf( "%d\n", &v);
  18. if ( 1 == v) { printf( "1\n"); continue;}
  19. a = v;
  20. s = log10_2_pi + (a+ 0.5)* log10(a) - a * log10_e;
  21. f = ceil(s);
  22. printf( "%d\n", f);
  23. }
  24. }
  25. return 0;
  26. }

第三题、求一个数的n次方8进制时的位数,换底公式!!!

https://www.nowcoder.net/acm/contest/75/A

代码:


 
 
  1. #include<map>
  2. #include<vector>
  3. #include<queue>
  4. #include<cstdio>
  5. #include<cstdlib>
  6. #include<cstring>
  7. #include<iostream>
  8. #include<algorithm>
  9. #include<cmath>
  10. #define maxn 100010
  11. using namespace std;
  12. typedef long long ll;
  13. #define E 2.71828182845
  14. #define PI 3.1415926
  15. int main(){
  16. ll n,t;
  17. scanf( "%lld",&t);
  18. while(t--)
  19. {
  20. ll ans= 1;
  21. scanf( "%lld",&n);
  22. if(n> 3)
  23. {
  24. ans=( log10( sqrt(( long double) 2.0 *PI*n))+(n*( log10(( long double)n)- log10(( long double)E))))/ log10( 8)+ 1;
  25. }
  26. printf( "%lld\n",ans);
  27. }
  28. return 0;
  29. }






  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值