题目:
满足 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)))。
至此我们通过找规律和二分查找成功解决问题。
注:其实一开始我也只是意识到有规律并没有准确找到,这道题是看过题解后才写出来的,还是差太多了,一起加油吧各位。