码迷,mamicode.com
首页 > 其他好文 > 详细

POJ1423 HDU1018 【斯特林公式】【高精度】

时间:2015-04-14 19:49:23      阅读:167      评论:0      收藏:0      [点我收藏+]

标签:

题目链接:

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

http://acm.hdu.edu.cn/showproblem.php?pid=1018


题目大意:

求N!有多少位。1<=N<=10^7。


思路:

N的规模很大。不能直接模拟求位数。先考虑这种做法:

设A = N! = 1*2*3*4*…*N,那么位数就是(int)log10(A) + 1

而(int)log10(A)  = log10(1*2*3*…*N) = log10(1) * log10(2) * log10(3) * … * log10(N)

这样累加起来就是结果了。不过因为N是10^7规模的,所以这样累加在HDU上可以AC,但是

POJ上还是超时的。

应该用斯特林公式来做。Stirling公式:当N足够大时,N! = (N/e) * N * sqrt(2*pi*N)。

log10(N) + 1 = (int)( log10(2*pi*N)/2 + N*log10(N/e) + 1。用到了常数e和π。为了保证精

度,定义常数e = 2.7182818284590452354,定义pi = 3.1415926535897932385。


AC代码:

//POJ1423
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const double e = 2.7182818284590452354;
const double pi = 3.1415926535897932385;

double Strling(int N)
{
    return 0.5*log10(2*pi*N) + N*log10(N/e);
}

int main()
{
    int T,N;
    cin >> T;
    while(T--)
    {
        cin >> N;
        cout << (int)Strling(N)+1 << endl;
    }

    return 0;
}

//HDU1018
# include<stdio.h>
# include<math.h>

int main()
{
    int n,m,i;
    double sum;
    scanf("%d",&n);
    while(n--)
    {
        scanf("%d",&m);
        sum = 0;
        for(i=1;i<=m;i++)
            sum += (log10(i));
        printf("%d\n",(int)sum+1);
    }
    
    return 0;
}


POJ1423 HDU1018 【斯特林公式】【高精度】

标签:

原文地址:http://blog.csdn.net/lianai911/article/details/45045811

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!