N的阶乘(N!)中的末尾有多少个0?
2015-08-12 11:11
459 查看
前段时间在《编程之美》中也遇到了该问题,昨天在做中国某IT公司的在线笔试题的时候,也遇到了该问题,不过之前一直没有完全理解这个问题的真正解决方式,昨天晚上在睡觉前才想明白(不好意思,智商让各位捉急了 T_T)。
N的阶乘(N!)中的末尾有多少个0? 如:N = 5,N! = 120.末尾有1个0.
很多人遇到该问题的时候会想办法把阶乘的结果求出来 ,然后再去数结果的末尾有多少个0,但是当N比较小的时候可以使用这种方式解决,当N比较大时,比如几百或者几千,甚至更大时,C++中的数据类型已经溢出,但是在Java中有一种专门针对大数相乘的计算方法,我们可以想象用这种方式的效率是什么情况,当然这也是一种解决方式。现在我们总结一下这个问题的解决方式:
第一种:先计算阶乘的结果,然后把末尾的0数出来(效率不高,并且会有溢出的风险)。
第二种:我们可以考虑一下,在N的阶乘中,只要末尾每出现一个0,表示在总结果中有一个10因子,而10因子可以用5*2表示,N的阶乘中每过五次才会出现一个5因子,但是每个两次就可以出现一个2因子,所以在阶乘中2因子的个数肯定比5因子的数量多;所以要找出有多少个10因子只需要找出5因子的数量就可以解决问题,那么现在问题就转换成了在N!中有多少个5因子。下面我们使用遍历方法计算,从1到N所有数字中5因子的个数。
第三种方法:该方法也是利用方法二中,计算5因子的个数来得出结果,但该方法不遍历所有数字。我们可以观察一组数字:
从1到,50之间包含5因子的数字的规律:
1*5=5, 2*5=10, 3*5=15, 4*5=20 ,5*5=25, 6*5=30,7*5=35, 8*5=40, 9*5=45 ,10*5= 50;(我们现在假设规律是:id*5=num)
所以在1到N的所有数字中,用N/5=n1(其中n1向下取整,如12.5时取12)就可以得出所有包含5因子的id序号个数;并且在id序列中可能还有5因子,我们就可以继续使用n1/5=n2;直到n2=0为止。这样在N较大的时候比前两种效率要高的多。闲话不多说,见代码:
N的阶乘(N!)中的末尾有多少个0? 如:N = 5,N! = 120.末尾有1个0.
很多人遇到该问题的时候会想办法把阶乘的结果求出来 ,然后再去数结果的末尾有多少个0,但是当N比较小的时候可以使用这种方式解决,当N比较大时,比如几百或者几千,甚至更大时,C++中的数据类型已经溢出,但是在Java中有一种专门针对大数相乘的计算方法,我们可以想象用这种方式的效率是什么情况,当然这也是一种解决方式。现在我们总结一下这个问题的解决方式:
第一种:先计算阶乘的结果,然后把末尾的0数出来(效率不高,并且会有溢出的风险)。
第二种:我们可以考虑一下,在N的阶乘中,只要末尾每出现一个0,表示在总结果中有一个10因子,而10因子可以用5*2表示,N的阶乘中每过五次才会出现一个5因子,但是每个两次就可以出现一个2因子,所以在阶乘中2因子的个数肯定比5因子的数量多;所以要找出有多少个10因子只需要找出5因子的数量就可以解决问题,那么现在问题就转换成了在N!中有多少个5因子。下面我们使用遍历方法计算,从1到N所有数字中5因子的个数。
#include <iostream> using namespace std; int main() { int N; while (cin>>N) { int count=0; int iTemp; for (int i=1;i<=N;++i) { iTemp=i; while ((iTemp%5)==0) { ++count; iTemp/=5; } } cout<<N<<"!"<<"末尾有"<<count<<"个0"<<endl; } return 0; }
第三种方法:该方法也是利用方法二中,计算5因子的个数来得出结果,但该方法不遍历所有数字。我们可以观察一组数字:
从1到,50之间包含5因子的数字的规律:
1*5=5, 2*5=10, 3*5=15, 4*5=20 ,5*5=25, 6*5=30,7*5=35, 8*5=40, 9*5=45 ,10*5= 50;(我们现在假设规律是:id*5=num)
所以在1到N的所有数字中,用N/5=n1(其中n1向下取整,如12.5时取12)就可以得出所有包含5因子的id序号个数;并且在id序列中可能还有5因子,我们就可以继续使用n1/5=n2;直到n2=0为止。这样在N较大的时候比前两种效率要高的多。闲话不多说,见代码:
#include <iostream> using namespace std; int main() { int N; while (cin>>N) { int count=0; int iTemp=N; while (iTemp/=5) { count+=iTemp; } cout<<N<<"!"<<"末尾有"<<count<<"个0"<<endl; } return 0; }
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- 动易2006序列号破解算法公布
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C++联合体转换成C#结构的实现方法
- C#实现的算24点游戏算法实例分析
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析