蓝桥杯——求阶乘(JAVA)

文章讨论了一种通过二分查找算法解决寻找最小的N值,使得N的阶乘末尾恰好有K个零的问题。关键在于理解阶乘末尾零的数量由因子5的个数决定,然后通过二分法在给定的范围内查找满足条件的最小N值。代码示例使用Java实现,并给出了思路解析。
摘要由CSDN通过智能技术生成

题目:

满足 N ! 的末尾恰好有 K 个 0 的最小的 N 是多少?

如果这样的 N 不存在输出 −1 。

输入格式

一个整数 K 。

输出格式

一个整数代表答案。

样例输入

2

样例输出

10

评测用例规模与约定

对于 30% 的数据, 1≤K≤106.

对于 100% 的数据, 1≤K≤1018.

运行限制

  • 最大运行时间:3s
  • 最大运行内存: 512M

代码: 

import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
   public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        long K=sc.nextLong();               //输入K
        long left=1;                        //左边界
        long right=Long.MAX_VALUE-1;         //右边界
        while(left<right){                   //二分法查找,因为要找最小值所以要令其不符合条件时自动退出循环,不能使用break语句停止。left(左边界)right(右边界)
            long mid=(left+right)/2;
            if (f(mid)<K){
                left=mid+1;
            }
            if (f(mid)>=K){
                right=mid;
            }
        }
        if (f(right)==K){               //符合条件输出值,不符合条件输出-1
            System.out.println(right);
        }else {
            System.out.println("-1");
        }
        sc.close();

    }
    public static long f(long a){    //看有几个五来确定末尾有几个零
        long sum=0;
        while(a>0){
            sum+=a/5;
            a=a/5;
        }
        return sum;
    }
}

思路:看到题目我觉得这道题应该是找规律的(K的取值那么大总不可能是暴力输出吧(doge)),然后发现5的时候末尾有一个0,10的时候末尾有两个0,15的时候末尾有三个0。

那么这题的规律就来了。

一个数的阶乘末尾如果想有0,那么就要乘10,而2*5=10(剩下的7个数相乘凑不出来10),所以我们就需要找有几个2*5,因为2比5小所以在一个数的阶乘中,包含2的个数一定比5的个数多,所以转换成我们需要求5的个数。下面举几个例子帮助大家理解

5!=1*2*3*4*5   其中有5/5=1个5。

10!=1*2*3*......*9*10     其中有10/5=2个5。

13!=1*2*3*.....*12*13     其中有13/5=2个5。

25!=1*2*3*....*24*25   其中有25/5=5个5(等等好像不对)25!中应该有6个5吧我们来数一下,5=1*5,10=2*5,15=3*5,20=4*5,25=5*5。25可以分解为两个5,相应的125可以分解成3个5相乘,所以我们要用循环将其除尽才能得出正确的5的个数。

好规律找到了(阶乘末尾有几个0取决于该数可以分解出几个5),我们就需要进行查找了,这里我们选择使用二分法(因为快)。

使用二分法就需要找左右边界,左边界很好找就是1,右边界呢?

因为

Long.MAX_VALUE的阶乘后边有   2305843009213693937个0(10的19次方) > k
Long.MAX_VALUE/2的阶乘后边有 1152921504606846964个0(10的19次方) > k
(其它博主的文章里复制的)

这里给上原文链接:http://t.csdn.cn/rDIsy

所以右边界我们就用Long.MAX_VALUE为了防止在二分时相加越界,所以右边界用Long.MAX_VALUE-1(减几都可以(也不能减太多(doge)))。

至此我们通过找规律和二分查找成功解决问题。

注:其实一开始我也只是意识到有规律并没有准确找到,这道题是看过题解后才写出来的,还是差太多了,一起加油吧各位。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值