N的阶乘(N!)中的末尾有多少个0?

前段时间在《编程之美》中也遇到了该问题,昨天在做中国某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因子的个数。
#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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值