数学题,百度的算法如下:
算法Stirling:
log10(n!)=log10(1*2*3…*n)=log10(1)+log10(2)+…+log10(n)
用于把求“位数”的问题转换成求对数。但是用这个方法超时了。。。。
另一个公式
n! = sqrt(2*π*n) * ((n/e)^n) * (1 + 1/(12*n) + 1/(288*n*n) + O(1/n^3))
π = acos(-1)
e = exp(1)
两边对10取对数
忽略log10(1 + 1/(12*n) + 1/(288*n*n) + O(1/n^3)) ≈ log10(1) = 0
得到公式
log10(n!) = log10(sqrt(2 * pi * n)) + n * log10(n / e)。
#include<iostream>
#include<math.h>
using namespace std;
int n;
const double e = 2.7182818284590452354;
const double pi = 4.0 * atan(1.0);
double f( int a ){
return log10( sqrt( 2 * pi * a ) ) + a * log10( a / e );
}
int main()
{
int i;
cin>>i;
while(i--){
cin>>n;
if( n == 1)
cout<<"1"<<endl;
else
cout<<(int)ceil(f(n))<<endl;
}
}
最后得到结果
:1. 原题是说输入一个n,后面再输入n个数,原来输出的时候,输入一个,处理一个是可以的。
2. double pi = 4.0 * atan(1.0); double pi = acos(-1.0); double pi = exp(1.0);
3. 公式
log10(n!) = log10(sqrt(2 * pi * n)) + n * log10(n / e)。