CSDN链接,有什么问题可以来私信一起讨论,加油

  1. package LanqiaobeiExam._13JB;
  2. import java.util.Scanner;
  3. /**
  4. * ClassName: 求阶乘
  5. * Package: LanqiaobeiExam._13JB
  6. *
  7. * @DATE: 2022/5/15 14:34
  8. * Author: asleep
  9. */
  10. public class 求阶乘 {
  11. /*
  12. * 0的数量只和 2 5相关,在结成中每遇到一个 5 肯定遇到两个或者多个 2 (10其实就是2*5构成的,无需单独考虑)
  13. * 因此只需要记录5的数量即可
  14. *
  15. * !!!错误方向:我们发现25是两个五,得出6个五为一组,然后推出结论,
  16. * !!!错误原因:25是两个五,等到125就是三个五,625就是四个五,无法分为具体几个一组(很多人都没向后想)
  17. * 我还记得当时我分享解题思路的时候,有个博主和我说没必要,动态规划即可,六个一组就行,狗头保命
  18. * 这里并不是说什么对错,而是对于一个题如果有讨论有争议,等学会以后你会对这个题印象更加深刻,多交流,加油
  19. *
  20. * 正确方向:25是有2个5,125是3个5,问题是怎么确定有几个25,几个125呢
  21. * 我们假设n个0,n/5就是有多少个5,
  22. * n/25是有多少个25,25里面有两个5,但是我们/5的时候其实一个5已经被计算好了
  23. * 所以我们只需要计算n/25就行了,
  24. * n/125同理,125是3个5,我们/5和/25的时候计算了当前125的2个5,n/125即可计算出最后一个5
  25. * …………
  26. * 大家可以拿个笔,拿个纸画一画
  27. *
  28. * 现在我们可以根据n个0求出来这个数是多少
  29. * 我们二分这个数字,然后检查他是否有n个0,
  30. * 如果二分出来的数字,并没有n个0,则证明当前n不存在对应的数字
  31. */
  32. //先把5的n次方求出来,因为数据范围为1e18,只需要找到长度为18的数字即可(记得用long)
  33. static long[] num = {5L, 25L, 125L, 625L, 3125L, 15625L, 78125L, 390625L, 1953125L, 9765625L, 48828125L, 244140625L, 1220703125L, 6103515625L, 30517578125L, 152587890625L, 762939453125L, 3814697265625L, 19073486328125L, 95367431640625L, 476837158203125L, 2384185791015625L, 11920928955078125L, 59604644775390625L, 298023223876953125L, 1490116119384765625L, 7450580596923828125L};
  34. public static void main(String[] args) {
  35. // long temp = 1L;
  36. // for (long i = 1L; i <= 50; i++) {
  37. // temp *= 5;
  38. // System.out.print(temp + "L, ");
  39. // }
  40. Scanner sc = new Scanner(System.in);
  41. long n = sc.nextLong();
  42. long left = 0L, right = (long) 9e18; //二分范围
  43. while (left < right) { //二分目标值
  44. long mid = (left + right) / 2;
  45. if (check(mid) < n) {
  46. left = mid + 1;
  47. } else {
  48. right = mid;
  49. }
  50. }
  51. if (check(right) == n) { //如果二分出来的结果不符合,则输出-1
  52. System.out.println(right);
  53. } else {
  54. System.out.println(-1);
  55. }
  56. }
  57. public static long check(long n) {
  58. long res = 0L;
  59. for (int i = 0; i < num.length; i++) {
  60. res += n / num[i];
  61. }
  62. return res;
  63. }
  64. }
点赞(0)
 

9.1 分

12 人评分

 

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 1 条评论

yzy 1年前 回复TA
你这个check要打表而且抽象 
public static long check(long x) {
        long ans = 0;
        while (x > 0) {
            ans += x / 5;
            x /= 5;
        }