当前位置:   article > 正文

蓝桥杯准备——BigIntenger(大数类型)以力扣每日一题“ 阶乘后的零”为例_蓝桥杯可以用biginteger

蓝桥杯可以用biginteger

今天准备蓝桥杯的时候遇到了一道大数类型的题目,尝试,int和long均不行后才发现这是一道大数类型题目。题目如下:

  1. 给定一个整数 n ,返回 n! 结果中尾随零的数量。
  2. 提示 n! = n * (n - 1) * (n - 2) * ... * 3 * 2 * 1
  3. 示例 1
  4. 输入:n = 3
  5. 输出:0
  6. 解释:3! = 6 ,不含尾随 0
  7. 示例 2
  8. 输入:n = 5
  9. 输出:1
  10. 解释:5! = 120 ,有一个尾随 0
  11. 示例 3
  12. 输入:n = 0
  13. 输出:0
  14. 提示:
  15. 0 <= n <= 104
  16. 进阶:你可以设计并实现对数时间复杂度的算法来解决此问题吗?

我的尝试:思路:不就是解决阶乘后的零问题吗,从几开始阶乘以及告诉我了,就是n,那还不简单,直接从n乘到1,然后用一个循环倒着遍历就行了吗,遇到0就加一,遇到第一个不是0的就跳出循环不就完了吗,于是写下的如下代码:

  1. package test;
  2. import java.util.Scanner;
  3. public class Main {
  4. public static void main (String[] args) {
  5. Scanner scanner = new Scanner(System.in);
  6. int n=scanner.nextInt();
  7. long sum=1;
  8. for(int i=0;i<n;i++) {
  9. sum=sum*(n-i);
  10. }
  11. int sum1=0;
  12. String string=Long.toString(sum);
  13. String[] s = string.split("");
  14. for(int i=s.length-1;i>=0;i--) {
  15. if(s[i].equals("0")) {
  16. sum1++;
  17. }else {
  18. break;
  19. }
  20. }
  21. if(n==0) {
  22. sum1=0;
  23. }
  24. else {
  25. }
  26. System.out.print(sum1);
  27. }
  28. }

于是就很愉快的只通过了测试数据中的21/50,

 我一看测试数据:30?30的阶乘,那不是大数了吗,这才反应过来要用大数来做。(之前尝试过long类型也不行)(int最多表示 2^31-1)

BigInteger类型的数字范围较Integer,Long类型的数字范围要大得多,它支持任意精度的整数,也就是说在运算中 BigInteger 类型可以准确地表示任何大小的整数值而不会丢失任何信息。

更多关于Intenger的信息可以参考这篇博客:Java中BigInteger类的使用方法详解,常用最全系列!_Java Punk的博客-CSDN博客_biginteger用法

 其实,BigInteger的构造方法与String非常相似,只是大数类型的定义需要在括号里写上Str还有可能写上数据的类型,支持各种进制。如下以2进制为例子:

  1. //进制转换
  2. @Test
  3. public void testScale() {
  4. //在构造将函数时,把radix进制的字符串转化为BigInteger
  5. String str = "1011100111";
  6. int radix = 2;
  7. BigInteger interNum1 = new BigInteger(str,radix); //743
  8. //我们通常不写,则是默认成10进制转换,如下:
  9. BigInteger interNum2 = new BigInteger(str); //1011100111
  10. }

当然BigInteger也可以由键盘读入:

  1. //读入方法:nextBigInteger()
  2. @Test
  3. public void test5() {
  4. Scanner scan = new Scanner(System.in); // 读入
  5. int n = scan.nextInt(); // 读入一个int;
  6. BigInteger m = scan.nextBigInteger(); // 读入一个BigInteger;
  7. while(scan.hasNext()){
  8. System.out.print("scan.hasNext()=" + scan.hasNext());
  9. }
  10. }

到这里我们就可以解决问题了吗?不行,原因是我们虽然知道了怎么构造大数类型,但是我的大数产生的途径是不断成出来的,怎么由整数类型成出大数类型呢?

有办法,而且说出来你可能要笑:把原来的整数全部定义为大数不就行了吗?哈哈哈哈哈!!!

如下:我们先需要把原有的String类型的数,再将其变为BigInteger类型。

  1. package test;
  2. import java.math.BigInteger;
  3. import java.util.Scanner;
  4. public class Main {
  5. public static void main (String[] args) {
  6. Scanner scanner = new Scanner(System.in);
  7. int n=scanner.nextInt();
  8. BigInteger sum=new BigInteger("1");
  9. for(int i=0;i<n;i++) {
  10. String temp=Integer.toString(n-i);
  11. BigInteger big = new BigInteger(temp);
  12. sum=sum.multiply(big);
  13. }
  14. int sum1=0;
  15. String string=sum.toString();
  16. String[] s = string.split("");
  17. for(int i=s.length-1;i>=0;i--) {
  18. if(s[i].equals("0")) {
  19. sum1++;
  20. }else {
  21. break;
  22. }
  23. }
  24. if(n==0) {
  25. sum1=0;
  26. }
  27. else {
  28. }
  29. System.out.print(sum1);
  30. }
  31. }

我们以为大功告成了,然而.......

我们却得到了:

 神马?7268,你逗我呢,不就50个测试用例吗,不1-50就行了吗,这也太过分了吧,大的有点离谱了吧!!!

于是我又开始了我漫长的思考,确实,如果要算7268的阶乘,大数也难做到啊,但是我们不是只需要阶乘最后的0的个数吗,是不是根本不用暴力的把阶乘真正的求出来,而只需要看最后的0有几个就好了呢?

实在想不出来了,我就去看了官方题解:

当时进入这个官方题解就给我一种不好的预感,因为我看见了“不祥之兆”的标签:

 脑筋急转弯!!!md

结果不出我所料:官方题解中连一个大数;类型的影子都没看见,甚至只用了5行代码就解决了这个问题:数学方法+脑经急转弯!!!

思路如下:

  1. n! 尾零的数量即为 n!n! 中因子 1010 的个数,而 10=2\times 510=2×5,因此转换成求 n!n! 中质因子 22 的个数和质因子 55 的个数的较小值。
  2. 由于质因子 55 的个数不会大于质因子 22 的个数(具体证明见方法二),我们可以仅考虑质因子 55 的个数。
  3. 而 n!n! 中质因子 55 的个数等于 [1,n][1,n] 的每个数的质因子 55 的个数之和,我们可以通过遍历 [1,n][1,n] 的所有 55 的倍数求出。

代码如下:

  1. class Solution {
  2. public int trailingZeroes(int n) {
  3. int ans = 0;
  4. for (int i = 5; i <= n; i += 5) {
  5. for (int x = i; x % 5 == 0; x /= 5) {
  6. ++ans;
  7. }
  8. }
  9. return ans;
  10. }
  11. }

测试一下:果然:

 果然是大佬!!!我这个菜鸡实锤!!!蓝桥杯不参加也罢!!!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/967648
推荐阅读
相关标签
  

闽ICP备14008679号