阶乘的定义:N! = 1*2*…*N
题意:
给你一个后尾0的个数,要你求,这可能是哪个数的阶乘,只求其最小值
分析:
1.这个 10=2*5 且 任意连续的5个数值以内,2的倍数一定大于5的倍数
所以,这题求后尾0 变成了求某5倍数的阶乘的 5的因子个数
2.对此,后尾0数目高达1e8,5的倍数可能的数据,我是预估在1e10左右。
所以必须化n->logn(即可以二分解决),即从1-1e10进行二分排查。
3.任意一个数值阶乘寻找其5的因子个数,就是(b*5)+(c*5*5)+...n*5^n转化为b+c+...n 详情看打表函数进行判断
1.对于一个数的阶乘,找到其后尾0的个数,就是5的因子个数
typedef long long ll;
const ll maxn=1e10;
ll getp(ll sum){
ll n=0;
while(sum){
n+=sum/5;
sum/=5;
}
return n;
}
2.主函数(二分)
scanf("%d",&t);
ll n;
for(int i=1;i<=t;i++){
scanf("%lld",&n);
ll low=1,high=maxn/5;//我是直接排除不是5倍数的数值进行二分
flag=0;
ll mid,m,ans;
while(low<=high){
mid=(low+high)/2;
m=getp(mid*5);
if(m==n){
ans=mid;
flag=1;
break;
}
else if(m>n){
high=mid-1;
}
else low=mid+1;
//printf("%lld\n",m);
}
if(flag)printf("Case %d: %lld\n",i,ans*5);
else printf("Case %d: impossible\n",i);
}
3.我是打表函数
int main(){
int sum=0;
//freopen("4.txt","w",stdout);
for(int i=5;i<=1000;i+=5){
int n=i;
int last=sum; //上一个的5因子个数
while(n%5==0&&n>=5){
n/=5;
sum++;//这次的5因子个数
}
printf("num(5)[%d]=%d 本次多了几个因子=%d \n",i,sum,sum-last);
}
return 0;
}
水平有限,若有错误,欢迎指正。
之前一直在忙考试,最近要继续码代码了。
如果你们觉得写的不错,那帮我点个赞吧!