问题:偶然看到有帖子讨论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个数 1031
input:2016
output:
阶乘结果包含所有的0个数 1006