这题还是自己想出来的,也是受白书上一题的启发(大概是求和大组合数有关的问题)。
题目要求n!最左边的那个数。
n!的增长速度是非常快的,并且这题的n也比较大,O(n)的做法应该是会TLE的。
考虑对n!取对数,当n比较小的时候(我取的大概是1w),可以直接求对数然后取小数位,再查对数表就可以知道最左边那一位了。
当n比较大的时候,我们就要利用一个叫做斯特灵公式的东西。然后再求对数。
#include "cstdio"
#include "cmath"
#define eps 1e-7
#define PI acos(-1)
int main(){
int T;
scanf("%d",&T);
int n;
int i;
double save[11];
double ans;
double tt;
for(i=1;i<=10;i++) save[i]=log((double)i);
//for(i=1;i<=9;i++) {printf("%lf ",save[i]);}
//printf("\n");
while(T--){
scanf("%d",&n);
if(n<=10000){
ans=0;
for(i=1;i<=n;i++) ans+=log((double)i);
//printf("%lf\n",ans);
}else{
tt=(double)n;
ans=0.5*log(tt)+0.5*log(2.0*PI)-tt+tt*log(tt);
}
int k;
k=floor(ans/log(10.0)+eps);
//printf("%d\n",k);
ans-=k*log(10.0);
//printf("%lf\n",ans);
//while(ans>log(10.0)) ans-=log(10.0);
for(i=1;i<=10;i++){
if(ans<save[i]){
printf("%d\n",i-1);
break;
}
}
}
return 0;
}