求阶乘(JAVA)
题目:
满足 N ! 的末尾恰好有 K 个 0 的最小的 N 是多少?
如果这样的 N 不存在输出 −1 。
输入格式
一个整数 K 。
输出格式
一个整数代表答案。
样例输入
2
样例输出
10
评测用例规模与约定
对于 30% 的数据, 1≤K≤106.
对于 100% 的数据, 1≤K≤1018.
运行限制
最大运行时间:3s
最大运行内存: 512M
代码:
import java.util.Scanner; |
思路:
看到题目我觉得这道题应该是找规律的(K的取值那么大总不可能是暴力输出吧(doge)),然后发现5的时候末尾有一个0,10的时候末尾有两个0,15的时候末尾有三个0。
那么这题的规律就来了。
一个数的阶乘末尾如果想有0,那么就要乘10,而25=10(剩下的7个数相乘凑不出来10),所以我们就需要找有几个25,因为2比5小所以在一个数的阶乘中,包含2的个数一定比5的个数多,所以转换成我们需要求5的个数。下面举几个例子帮助大家理解
5!=12345 其中有5/5=1个5。
10!=123*……910 其中有10/5=2个5。
13!=123*…..1213 其中有13/5=2个5。
25!=123*….2425 其中有25/5=5个5(等等好像不对)25!中应该有6个5吧我们来数一下,5=15,10=25,15=35,20=45,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)))。
至此我们通过找规律和二分查找成功解决问题。
注:其实一开始我也只是意识到有规律并没有准确找到,这道题是看过题解后才写出来的,还是差太多了,一起加油吧各位。