问题描述
满足
N
!
{N}!
N! 的末尾恰好有 K 个 0 的最小的
N
{N}
N是多少?
(输入输出懒得放了,可以去官网上看看)
说明提示
对于
30
%
{30 \%}
30% 的数据,
1
≤
K
≤
1
0
6
{1 \leq K \leq 10^{6} }
1≤K≤106.
对于
100
%
{100 \%}
100% 的数据,
1
≤
K
≤
1
0
18
{ 1 \leq K \leq 10^{18}}
1≤K≤1018 .
运行限制
最大运行时间:3s
最大运行内存: 512M
思路
如果我们一个一个去暴力枚举阶乘后面的 0,对于这题的数据量来说是一定会超时的。
那我们不妨换个角度去想。
阶乘中需要得到末尾为0则需要有 5 和 2 这两个质因数,而 2 的质因数的数量一定是远远大于 5 的数量(只要是个偶数就能得出一个2的质因数)也就是说,需要找到阶乘中 5 的质因数的数量也就是末尾 0 的数量。
这题不妨可以采取二分法来获取需要的数字,注意数据的大小,我们用三个long类型的变量来存储二分的三个指针。(注意初始右端指针的赋值,最后一个测试点会卡这个)
如果二分查找得到了结果后,这个时候的阶乘值也不一定是我们需要的最小值,需要往前递推,直到上一个值的阶乘失去了一个5的质因子。
至于获取阶乘质因数的方法。大家可以参考这篇博客。
https://blog.csdn.net/alex_yuqian/article/details/92367397?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167912337516800222894645%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=167912337516800222894645&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-1-92367397-null-null.142v74wechat,201v4add_ask,239v2insert_chatgpt&utm_term=%E9%98%B6%E4%B9%98%E5%9B%A0%E5%AD%90%E4%B8%AA%E6%95%B0&spm=1018.2226.3001.4187
代码
package 蓝桥杯省赛;
import java.util.Scanner;
public class Q2145 {
public static void main(String[] args) {
// TODO 自动生成的方法存根
Scanner input = new Scanner(System.in);
long k =input.nextLong();
long l = 1;
long r = (long)9e18;
long index;
while(l <= r) {
index = (l+r)/2;
//这里取到的数字不一定是我们需要的最小阶乘
if(getnum(index, 5) == k) {
while(index >= 0 && getnum(index, 5) ==k) {
index--;
}
System.out.print(index+1);
break;
}
else if (getnum(index,5) < k) {
l = index + 1 ;
}
else if(getnum(index,5) > k) {
r = index -1;
}
}
if(l >r) {
System.out.println(-1);
}
}
public static long getnum(long num,long k) {
long ans = 0;
while(num > 0) {
ans += num/k;
num = num/k;
}
return ans;
}
}
总结
思考
这道题给我的思考主要是关于二分查找优化时间以及如何找阶乘的质因数的数量,以及这种题目的数据量如何处理。
其他
这题是去年本人参加蓝桥杯的一题,当时忘记了有没有直接输出-1来拿样例分,替大家试过了直接输出-1能过两个样例:)