51nod1130---斯特林公式

题目链接:51nod1130

求位数公式是 log10(n)+1  然后此题让求的是n的阶乘的位数 

那么很多同学会想到  log0(N!)=log10(1*2*3...*N)+1 = log10(1)+log(2)+log(3)+....+log(N)+1

但是这道题N最大是1e9  所以这种方法肯定会超时   所以我们需要用新的方法

斯特林公式能够近似的求出n的阶乘的值  然后我们再用  求位数公式  log10(n)+1就可以求出答案

斯特林公式   sqrt( 2*pi*n ) * pow( n/e , n)

斯特林公式 

而且  log10()内的乘法 又可以转化为加法  那么我们就可以对斯特林公式优化为

    0.5 * log10( 2*PI*n ) + n*log10( n/e )

要注意   公式里用到了 e 和 π   我们定义他们有两种写法

#define PI acos(-1.0)
#define E exp(1.0)

const double e = 2.718281828459;
const double pi = 3.1415926535;

建议大家使用第一种  

exp()是e的指数幂   括号内是double型   返回值也是double    e(1.0)=e^1=e    ,e(-1.0)=e^-1

acos()是反三角函数   括号内是double型   返回值也是double  acos(-1.0)=π

尤其是这道题  数据特别的卡 刚开始 我定义e =2.71828182845; 疯狂的wa  wa了七八遍后  我又多加了一位e =2.718281828459  就对了。。。

所以  由于有的时候 我们不知道数据需要几位  用赋值的定义方式就可能出错

代码

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
using namespace std;
typedef long long ll;
#define PI acos(-1.0)
#define E exp(1.0)
const double e = 2.718281828459;
const double pi = 3.1415926535;
int T;
double n;
int main(){
    scanf("%d",&T);
    while(T--){
        scanf("%lf",&n);
        ll ans=(ll)(0.5*log10(2*PI*n) + n*(log10(n/E)) +1);
        printf("%I64d\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/holly_Z_P_F/article/details/84671287
今日推荐