十三届蓝桥杯JavaB组G:求阶乘

问题描述

满足 N ! {N}! N! 的末尾恰好有 K 个 0 的最小的 N {N} N是多少?
输入输出懒得放了,可以去官网上看看

说明提示

对于 30 % {30 \%} 30% 的数据, 1 ≤ K ≤ 1 0 6 {1 \leq K \leq 10^{6} } 1K106.
对于 100 % {100 \%} 100% 的数据, 1 ≤ K ≤ 1 0 18 { 1 \leq K \leq 10^{18}} 1K1018 .

运行限制

最大运行时间: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能过两个样例:)

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值