题目链接:

​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;
}