loj 1138 - Trailing Zeroes (III) ( 数论 规律 )

1 篇文章 0 订阅
1 篇文章 0 订阅

给定p,求最小的n使得n!的末尾含有p个0

 

对于n!可对其分解质因数如下:

n!=1*2*3*...*n

  =(1)*(2)*(3)*(2*2)*(5)*(2*3)*...

要末尾有0很明显要质因数中要有2和5

而2出现的频率显然比5高

所以5的个数即为阶乘末尾0的个数

 

至于求质因数中5的个数,以125为例:

对于125!,125/5=25,我们只关心其中含5的部分

即有125!=...*(1*5)...*(2*5)...*(3*5)...*(4*5)...*(5*5)......*(25*5) (此时未完全分解为质因数),这时得到25个5

再把其中与5相乘的1、2、3、4、5、。。。、25提取出来,即得到25!

对于25!,25/5=5,同样只关心其中含5的部分

25!=.....*(1*5)*...*(2*5)...*(3*5)...*(4*5)...*(5*5),这时得到5个5

然后再把与5相乘的1、2、3、4、5提取出来,得到5!

很明显5!中含有一个5,

于是我们可以得到125!含有25+5+1=31个5,而2的个数显然比5多,于是可以得出125!的末尾有31个0

 

这样就能得到任意n!的末尾有多少个0

而题目最多要求1e8个0,当n为400000016时末尾的0就已达到,而n至少为5时末尾才有0

所以对于每次给定的q,二分上下极限求0的个数是否等于q即可

 

 

#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

long long  cntzero(long long n)
{
    long long cnt=0;
    while(n)
    {
        cnt+=n/5;
        n/=5;
    }
    return cnt;
}

int main()
{
    //freopen("in","r",stdin);

    long long t,q,l,r,m;
    cin>>t;
    for(long long i=1;i<=t;i++)
    {
        cin>>q;
         r=400000016;
         l=4;
        while(l<=r)
        {
            m=(r-l)/2+l;
            if(cntzero(m)>=q)
            r=m-1;
            else
            l=m+1;
        }
        if(cntzero(l)==q)
        cout<<"Case "<<i<<": "<<l<<endl;
        else
        cout<<"Case "<<i<<": impossible"<<endl;
    }
    return 0;
}

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值