关于这道题,见过两种问法:

  1. 给定参数n(n为正整数),请计算n的阶乘n!末尾所含“0”的个数。
  2. (n!%(10^k)) == 0。已知n,求能使上式成立的K的最大值。

问题分析:
显然,对于阶乘这个大数,我们不可能将其结果计算出来,在统计其末尾所含有的“0”的个数。所以必须从其数字特征进行分析。

首先考虑一般的情形。对于任意一个正整数,若对其进行因式分解,那么其末尾的“0”必可以分解为2*5。这里每一个“0”必然和一个“2”与“5”对应。这里是阶乘,含有2的分解比含有5的分解多很多。所以这道题的是问:正整数n因式分解中“5”的个数。例如6的阶乘:

6! = 6 * 5 * 4 * 3 * 2 * 1
分解后
6! = (3*2)*5*(2*2)*3*2*1 = 5*3*3*2*2*2*2*1

从上面的例子可以看出,分解之后6的阶乘含有一个5,四个2,2的个数5多很多。

对于n<5,因为不含分解因子“5”,所以末尾没有0

但是对于n>=5的情况呢?我们可以把含有分解因子为“5”的给提出来,把n!变为

n! = [5m*5(m-1)*....*10*5]*a,a是一个不含因子“5”的整数,其中n = 5m + r (0<= r <= 4)

例如26的阶乘:

26! = [25*20*15*10*5]*26*24*23*22*21*19*......*1
26! = [(5*5)*(5*4)*(5*3)*(5*2)*5]*26*24*23*22*21*19*......*1
26! = [(5*5)*(5*4)*(5*3)*(5*2)*5]*a(a代表后面所有数相乘)

通过上面的分解我们很容易看出26的阶乘一共有6个分解因子“5”。但是特别大的正整数呢?我们可不能手写出来然后数个数,所以我们还要进一步分析。

m>=5 时,m本身也可以分解出“5”,所以我们需要在原有的基础上再加m分解后的“5”的个数,现在n的阶乘可以写为:

n! = 5^m * m! * a

推导过程是:

n! = [5m*5(m-1)*....*10*5]*a = [5*5*5....*5*m*m-1*m-2*.....*1]*a
整合之后得到
n! = 5^m * m! * a

通过上面的推导,我们可以得出最终的公式,令f(x)表示正整数x末尾所含有的“0”的个数, g(x)表示正整数x的因式分解中因子“5”的个数:

f(n!) = g(n!) = g(5^k * k! * a) = k + g(k!) = k + f(k!)

所以,最终的计算公式为:
当0 < n < 5时,f(n!) = 0;
当n >= 5时,f(n!) = k + f(k!), 其中 k = n / 5(取整)

到这里代码就写了,这不是递归调用嘛,所以代码写为:

int func(const int x)
{if ( x < 5){return 0;}int y = x / 5;return y + func(y);
}

但是递归调用涉及到函数的调用开销,效率并不高,我们既然有公式了,可以直接带入公式:

int func2(int x)
{int y = 0;while (x > 4){x = x / 5;y += x;}return y;
}

还有一种写法,我觉着比较难理解:

int func3(const int x)
{int y = 0;for (int i = 5; i <= x; i *= 5){y += x / i;}return y;
}

感谢大家,我是假装很努力的YoungYangD(小羊)。

参考资料:
https://www.cnblogs.com/hutonm/p/5624996.html

n的阶乘末尾含有“0”的个数相关推荐

  1. 阶乘末尾连续零的个数

    十进制中 N! 末尾连续零的个数 首先考虑 800 中有两个连续的零,800=$8*10^2$ 首先考虑 50 中有一个连续的零,50= $5*10^1$ 从上面可以看出,N! = $a*10^k$ ...

  2. 【算法】计算n阶乘中尾部0的个数

    题目 设计一个算法,计算出n阶乘中尾部零的个数样例 11! = 39916800,因此应该返回 2挑战 O(logN)的时间复杂度 题目分析 n阶乘中,尾部出现的零是10和10的倍数相乘的结果,尾部出 ...

  3. c语言 n阶阶乘尾0个数,计算n的阶乘(n!)末尾0的个数

    题目: 给定一个正整数n,请计算n的阶乘n!末尾所含有"0"的个数. 举例: 5!=120,其末尾所含有的"0"的个数为1: 10!= 3628800,其末尾所 ...

  4. java 阶乘后几位,java阶乘计算获得结果末尾0的个数代码实现

    看到题目后,分析了下, 10的阶乘就已经很大了.计算出来再得到这个末尾的0的个数,完全不现实,即使实现了也是很麻烦的. 后来想某个数的阶乘中乘积有5结尾的数字的时候就应该在结果的末尾产生一个0. 付诸 ...

  5. 求阶乘N!末尾0的个数

    POJ上有这个题目.http://poj.org/problem?id=1401.去掉一大堆没有用的信息,POJ的描述如下: For example, they defined the functio ...

  6. 统计阶乘结果的末尾0的个数

    统计结成结果的末尾0的个数 今天看到一道题目,是让求解 1024! 末尾的0的个数.对于这个问题,作者首先想到了蛮力法..先将阶乘的结果计算出来放入数组然后统计末尾0的个数.这样做的话首先得先进行较大 ...

  7. java n%9==0_用C++实现求N!中末尾0的个数的方法详解

    题目描述: 输入一个正整数n,求n!(即阶乘)末尾有多少个0? 比如: n = 10; n! = 3628800,所以答案为2 输入描述: 输入为1行,n(1≤n≤1000) 输出描述: 输出一个整数 ...

  8. 求一个整数的阶乘结果中后缀0的个数

    问题描述: 给一个整数,请输出该数字阶乘的后缀0的个数,例如: 数字7,它的阶乘为5040,后面有一个0,则输出1:还有数字10,它的阶乘为3628800,后面有两个0,则输出2. /* 功能:求一个 ...

  9. 整数阶乘尾部0的个数

    求解整数阶乘尾部0的个数主要是算出有多少个5及其倍数,因为这些数与偶数相乘会产生0,以100!的阶乘举例 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 ...

最新文章

  1. 在VMware15中创建虚拟机安装ubuntu系统(超详细教程)
  2. Navicat for MySQL连接MYSQL出错,错误代码1045的解决方法
  3. [解答] python下如何安装SocketServer?
  4. 单片机直接驱动段式液晶
  5. flash加载flv,本地测试正常,上传至空间则失败解决办法
  6. fileinput 图片上传
  7. [提示]普通用户使用sealos安装k8s集群的话,默认还是会装到root用户的home目录/root
  8. Effective Java之用接口模拟可伸缩的枚举(三十四)
  9. Python补充06 Python之道
  10. SVN中如何去除版本控制器
  11. Python 最难的问题
  12. 10个节约开发时间的CSS技巧
  13. 二分查找(binary_search)
  14. MySQL连接超时自动断开连接问题
  15. Intel MediaSDK sample_decode 官方GPU解码流程学习(二) - 在双显卡机器上实现DirectX11 D3D11和OpenCL共享资源
  16. 【托业】【怪兽】TEST02
  17. socketio使用
  18. 【信号检测】基于matlab自适应滤波法微弱信号检测【含Matlab源码 2308期】
  19. Jamie求职记--北邮信通小硕--技术类
  20. webstorm实现手机预览页面

热门文章

  1. 【博客545】从交换机视角看四种报文:广播、组播、未知单播、已知单播
  2. N皇后问题(C++)
  3. Hisi内核线程CPU占用高的问题
  4. 极品飞车最高通缉电脑秘籍和提示
  5. 关于NSString stringWithFormat输出“%”问题
  6. 转载——glPushMatrix(百度百科)
  7. 日志框架(2) : Log4j介绍及使用
  8. matlab传递函数参数辨识,5.2 传递函数的频域辨识 系统辨识理论及Matlab仿真课件.ppt...
  9. 【Ansible自动化运维工具】Ansible变量之Facts变量
  10. 零基础学模拟电路--1.认识运算放大器