数论基础:阶乘的后尾0个数Trailing Zeroes (III)

来源:互联网 发布:seo站外怎么优化 编辑:程序博客网 时间:2024/06/11 11:05

阶乘的定义: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;}

水平有限,若有错误,欢迎指正。

之前一直在忙考试,最近要继续码代码了。
如果你们觉得写的不错,那帮我点个赞吧!

阅读全文
0 0
原创粉丝点击