二分应用题 [蓝桥杯2022年省赛真题] 求阶乘

题目描述

满足N!的末尾恰好有K个0的最小的N是多少?
如果这样的N不存在输出-1。

输入格式

一个整数K。
对于30% 的数据,1≤K≤10^6。
对于100% 的数据,1≤K≤10^18。

输出格式

一个整数代表答案。

输入样例

2

输出样例 

10

解法:要满足尾数有0,则这个阶乘中一定包含10的因子,而10由2和5组成,所以其实就是判断以下有多少个2*5的因子,由于2的数量一定是比5大的,所以我们只需要计算一下N这个数字的阶乘里有多少个5这个因子,就可以判断末尾有几个0!

所以关键点在于,如何计算 N的阶乘有多少个5

这里就直接说方法啦,只需要让N不断除以5,直到N除不了就可以了。

比如25,25/5=5, 有5个5,5/5=1, 所以25的阶乘里总共有6个5,也就有6个尾数0

又因为,当N越大,出现的尾数0才可能越多,即尾数0的个数是随着N的增大而增大的,具有单调性,所以可以对N进行二分查找,降低时间复杂度。

AC代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll k;
ll check(ll x)
{
    ll res=0;
    while(x)
    {
        res=res+ x/5;
        x/=5;
    }
    return res;
}
int main()
{
    scanf("%ld",&k);

    ll l = 0 , r = 1e19;

    while(l<r)
    {
        ll mid =(l+r)/2;
        if(check(mid)>=k)r=mid;
        else l = mid + 1 ;
    }
    if(check(l)==k)cout<<l<<endl;
    else cout<<"-1"<<endl;
    return 0;
}

  • 12
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值