一道大数题目,本来想用大数运算做,考虑到数目太大 10^7,觉得应该有其他更有效的方法。
方法1:分解法:
log10(n!)=log10(1*2*3…*n)=log10(1)+log10(2)+…+log10(n)
#include<cstdio>
#include<cmath>
using namespace std;
int main(){
long long n, k;
scanf("%lld", &n);
for(int i = 0; i < n; i++){
scanf("%lld", &k);
double len = 0;
for(long long i = 1; i <= k; i++){
len += log10(double(i));
}
printf("%lld\n", (long long)(len) + 1);
}
return 0;
}
方法2 :斯特林公式法
当n增加时,(ln n!)与o (n ln n − n)之比趋于1。
#include<cstdio>
#include<cmath>
using namespace std;
const double e = 2.71828182846;
const double pi = 3.1415926536;
int main(){
long long n, k;
scanf("%lld", &n);
for(int i = 0; i < n; i++){
scanf("%lld", &k);
if(k == 1){
printf("1\n");
}
else{
long long len = log10(sqrt(2 * pi * k)) + k * log10(double(k / e));
printf("%lld\n", len + 1);
}
}
return 0;
}
用斯特林公式有一点要考虑到,不能直接应用公式,而要将公式变形,否则处理特大数的时候会发生错误。