斯特林公式是一条用来取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还是自己打个表吧,很简单的。
代码:
-
#include<stdio.h>
-
#include<math.h>
-
#include<stdlib.h>
-
#define e 2.71828182845
-
#define pi 3.1415926
-
int main()
-
{
-
long a ;
-
double s ;
-
int result =
0 ;
-
while(
scanf(
"%d", &a ) != EOF )
-
{
-
if ( a >
3 && a !=
7 && a !=
8 )
-
{
-
s =
0.5 *
log10 (
2 * pi * a ) + a * (
log10 ( a ) -
log10(e) ) ;
-
s = s - (
int ) s ;
-
result = (
int )
pow (
10 , s ) ;
-
printf(
"%d\n",result ) ;
-
continue ;
-
}
-
if ( a <=
1 ) {
printf(
"1\n");
continue ;}
-
if ( a ==
2 ) {
printf(
"2\n" ) ;
continue ; }
-
if ( a ==
3 ) {
printf(
"6\n" ) ;
continue ;}
-
if ( a ==
7 ) {
printf(
"5\n");
continue ; }
-
if ( a ==
8 ) {
printf(
"4\n" ) ;
continue ; }
-
}
-
}
第二题:判断阶乘的位数。
http://poj.org/problem?id=1423
代码:
-
#include<stdio.h>
-
#include<stdlib.h>
-
#include<string.h>
-
#include<math.h>
-
const
double e =
2.71828182845;
-
const
double pi =
3.1415926;
-
int main(void)
-
{
-
int t, i, f, v;
-
double a, s;
-
-
const
double log10_e =
log10(e);
-
const
double log10_2_pi =
log10(
2.0*pi)/
2.0;
-
-
while (
scanf(
"%d", &t) != EOF && t)
-
{
-
for (i =
0; i < t; ++i)
-
{
-
scanf(
"%d\n", &v);
-
if (
1 == v) {
printf(
"1\n");
continue;}
-
a = v;
-
s = log10_2_pi + (a+
0.5)*
log10(a) - a * log10_e;
-
f =
ceil(s);
-
printf(
"%d\n", f);
-
}
-
}
-
return
0;
-
}
第三题、求一个数的n次方8进制时的位数,换底公式!!!
https://www.nowcoder.net/acm/contest/75/A
代码:
-
#include<map>
-
#include<vector>
-
#include<queue>
-
#include<cstdio>
-
#include<cstdlib>
-
#include<cstring>
-
#include<iostream>
-
#include<algorithm>
-
#include<cmath>
-
#define maxn 100010
-
using
namespace
std;
-
typedef
long
long ll;
-
#define E 2.71828182845
-
#define PI 3.1415926
-
int main(){
-
ll n,t;
-
scanf(
"%lld",&t);
-
while(t--)
-
{
-
ll ans=
1;
-
scanf(
"%lld",&n);
-
if(n>
3)
-
{
-
ans=(
log10(
sqrt((
long
double)
2.0 *PI*n))+(n*(
log10((
long
double)n)-
log10((
long
double)E))))/
log10(
8)+
1;
-
}
-
printf(
"%lld\n",ans);
-
}
-
return
0;
-
}
-