poj-1423 NYOJ_69 数字长度 斯特林公式 对数应用

数的长度

时间限制: 3000 ms  |  内存限制: 65535 KB
难度: 1
描述

    N!阶乘是一个非常大的数,大家都知道计算公式是N!=N*(N-1)······*2*1.现在你的任务是计算出N!的位数有多少(十进制)?

输入
首行输入n,表示有多少组测试数据(n<10)
随后n行每行输入一组测试数据 N( 0 < N < 1000000 )
输出
对于每个数N,输出N!的(十进制)位数。
样例输入
3

1

3

32000
样例输出
1

1

130271




刚拿到这个题,因为是在数学分类里的,我想着是不是又公式呀!!一般阶乘的题都有特殊方法,首先想到的是用数组存 高位数 的方法,但是当大于5000就开始慢了,要超时。没办法,看了留言
板,说是 可以用对数 或者斯特林公式。


对数的方法:
可设想n!的结果是不大于10的M次幂的数,即n!<=10^M(10的M次方),则不小于M的最小整数就是 n!的位数,对 该式两边取对数,有 M =log10^n! 即:M = log10^1+log10^2+log10^3...+log10^n 循环求和,就能算得M值,该M是n!的精确位数。当n比较大的时候,这种方法方法需要花费很多的时间。
View Code
#include <stdio.h>

#include <math.h>

int main()

{

int n,N,i;

double sum;

scanf("%d",&N);

while (N--)

{

scanf("%d",&n);

sum=1;

for(i=1;i<=n;i++)

sum+=log10((double)i);

printf("%d\n",(int)sum);

}

return 0;

}

斯特林公式:

log(n!) = log10(sqrt(2*pi*n)) + n*log10(n/e);

其中pi是圆周率,e是自然对数。
1时 要特殊处理:
View Code
#include <iostream>

#include <cstring>

#include <algorithm>

#include <cstdio>

#include <cmath>

#define e 2.718281828459045

#define pi 3.141592653589793239

using namespace std;

int main ()

{

    int cas,n;

    scanf("%d",&cas);

    while (cas --)

    {

          scanf("%d",&n);

          double t = log10(sqrt(2*pi*n)) + n * log10(n/e);

          printf ("%d\n",(int)t + 1);

    }

return 0;

}

 

你可能感兴趣的:(poj)