求N!末尾0的个数

此题n的取值可能很大,甚至会达到亿,这里我们区最大范围2000000000(2*10^9)。
分析一:
乘积末尾的0的个数依赖于因子中的2的个数和5的个数。对于阶乘来说,每2个数字就至少有一个2的因子,所以2的因子是足够的。5的因子相对少些,至少连续5个数才能保证一定出现一个。注意,这里连续5个书保证出现一个5的因子是指最少的情况。比如1,2,3,4,5,这就只会出现一个。但是考虑 21,22,23,24,25,25 = 5 * 5,所以如果乘以25那就能得到2个5的因子。 
为了解决这个问题,必须首先从数学上分析在N!结果值的末尾产生零的条件。不难看出:一个整数若含有一个因子5,则必然会在求N!时产生一个零。因此问题转化为求1到N这N个整数中包含了多少个因子5。若整数N能被25整除,则N包含2个因子5;若整数N能被5整除,则N包含1 个因子5。
这样可实现一下代码:
#include<iostream>
using namespace std;

int main()
{
 int num,i;
 long long n,m,count_5num;
 cin>>num;
 for(i=0;i<num;i++)
 {
  cin>>n;
  count_5num=0;
  while(n%5!=0)n--;
  while(n>0)
  {
   m=n;
   while(m%5==0)
   {
    count_5num++;
    m/=5;
   }
   n-=5;
  }
  cout<<count_5num<<endl;
 }
 return 0;
}

但是这个代码的缺点是,n极大,那么运行时间很长,
如运算2*10^8,可能需要五秒
运算2*10^9甚至需要几十秒
为此我做了如下改进:
分析二:
1、算出所有小于等于n且能被5整除的整数的个数------[n/5]
2、算出所有小于等于n且能被25整除的整数的个数-----[n/25]
3、算出所有小于等于n且能被125整除的整数的个数----[n/125]
...................
.................
...................
算出所有小于等于n且能被5^x整除的整数的个数--------[n/5^x](其中,5^x为小于等于n的5的最大次方)
这样,我们就能快速地算出行数字5这个因子的最大个数了
优化后的代码:
#include<iostream>
using namespace std;

int main()
{
 int num,i,count_5num;
 long long n,m;
 cin>>num;
 for(i=0;i<num;i++)
 {
  cin>>n;
  count_5num=0;
  for(m=5;m<=n;m*=5)
   count_5num+=(int)(n/m);
  cout<<count_5num<<endl;
 }
 return 0;
}

上述优化后的代码可使运算速度增大不少,运算2*10^9只需一秒不到
注意:
m,n,count_5num的类型要取long long型,long型都不可以,否则可能会出现count_5num累加反而会减小的情况。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值