Java 关于数N阶乘的结果包含多少个0的问题,分为末尾连续0的个数和所有0的个数

问题:偶然看到有帖子讨论2016!的结果含有多少个0 的问题

求N的阶乘后有多少个零的解法如下:

(1)原理说明:5和一个偶数(不考虑偶数0)相乘即可得到一个结果为10的倍数的数值,也就是说,产生了零。在1~ N 中找5,有 多少个5,就有多少个零。

  例如,15 =  5 * 3 ,即15有一个·5 ;20 = 5 * 4 ,即20有一个·5;

      25 = 5 * 5 ,即25有两个5 ;100 = 5 * 5 * 4 ,即100有两个5 ;

    125 = 5 * 5 * 5 ,即125有三个5 ;625 = 5 * 5 * 5 * 5 ,即625有四个5

(2)设5的 x 次方等于m,找到不大于数值N的那个最大的m值,也就确定了x和集合{1,2,3,.......,x}

(3)N 除以 (5的一次方),结果取整,假设为 a1

  N  除以 (5的二次方),结果取整,假设为 a2

          N  除以 (5的三次方),结果取整,假设为 a3

  类似地,直到

 N  除以 (5的 x 次方),结果取整,假设为 aX,

         则最后的结果为 (a1 + a2 + a3 + ..... + aX)  个零。


下面以2016的阶乘有多少个零 为例:

(1)5的四次方等于 625 <2016 , 5的五次方等于 3125 > 2016

(2)5  1 ~ 2016 中 是5 的倍数的数 有 403 个   (5 * 2 = 10)

  25 = 5 * 5 1 ~ 2016 中 是25 的倍数的数 80   (25 * 4 = 100)

125 = 5 * 5 * 51 ~ 2016 中 是125 的倍数的数 16 (125 * 8 = 1000)

 625 = 5 * 5 * 5  * 5 1 ~ 2016 中 是625 的倍数的数 3   (625 * 16 = 10000)

(3)最后的结果为 : 403 + 80 + 16 + 3 = 502 (个)

然后自己用自己的方法直接求2016!结果的0的个数,发现不对

这些博客并没有交代清楚问题的细节!!!坑!

实际上502是阶乘结果末尾连续的0的个数!


问题来源可能与POJ上的这道题比较相似:http://poj.org/problem?id=1401


我的测试:

package cugoj;

import java.math.BigInteger;
import java.util.Scanner;


/*描述:证明2018的阶乘结果中含有多少个0
 * 
 *思路 1:直接使用阶乘结果来统计
 *思路2:通过判断含有多少个5的因子(网上多数用的是这个办法,但是这个只能统计阶乘结果末尾有多少个连续的0)
 * */

public class Main2018 {

    public static void main(String[] args)
    {
        Main2018 m1=new Main2018();
        Scanner s1=new Scanner(System.in);
        
        while(s1.hasNext())
        {
            String input=s1.next();
            //System.out.println(m1.bignumJC(input)); //2018的阶乘结果无法输出
            System.out.println("阶乘结果末尾连续的0个数 "+m1.countCoZero(Integer.parseInt(input)));
            System.out.println("阶乘结果包含所有的0个数 "+m1.countCh(m1.bignumJC(input).toCharArray()));
        }
        s1.close();
    }
    
    private String bignumJC(String s)
    {

        BigInteger n = new BigInteger(s); 
        BigInteger a = new BigInteger("1");
        BigInteger b = new BigInteger("1");

        for (BigInteger i = new BigInteger("1"); i.compareTo(n) <= 0; i = i.add(a))// 忘记将自加后的赋值了
        {
            b = b.multiply(i);
        }
        
        return b.toString();
    }
    
    private int countCh(char[] a)
    {
        int res = 0;
        for (int i = 0; i < a.length; i++) {
            if (a[i] == '0') {
                res++;
            }
        }
        return res;
    }
    
    
    private int countCoZero(int a)
    {
        int res=0;
        while(a>=5)
        {
            a=a/5;
            res=res+a;
        }
        return res;
    }

}

input :2018

output: 

阶乘结果末尾连续的0个数 502
阶乘结果包含所有的0个数 1031 

input:2016

output:

阶乘结果末尾连续的0个数 502
阶乘结果包含所有的0个数 1006 

猜你喜欢

转载自blog.csdn.net/qq_28619473/article/details/80359153
今日推荐