题目链接:
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; }
时间: 2024-10-12 23:02:46