求0的个数

例题描述】求0的个数
求1* 2 * 3 * 4*… * N所得数末尾有多少个0?
样例输入
5
样例输出
1
方法一:
采用从1乘到N,每乘一次进行一次判断,若后面有零则去掉后面的0,并记下掉的0的个数,
并且为了不超过数的表示范围,去掉前面与0有关的数,只保留三位有效数字。

#include<iostream>
using namespace std;
int i,ii,n;
long sum;
 
int main()
{
	ii=0;
	sum=1;
	cin>>n;
	for(i=1;i<=n;i++)
	{
		sum=sum*i;
		while(sum%10==0)//将数字末尾的零去掉
		{
			sum=sum/10;
			ii=ii+1;//累加零的个数
		}
		sum=sum%1000;//保留三位有效数字
	}
	cout<<ii<<endl;
	return 0;
}//个人感觉第一种方法并不适用不是全排列的情况

方法二:
由于影响生成0的数只有2和5的倍数,并且真正影响生成0的是5的倍数,显然这些数的分解数含因子2的数显然多于因子5
的数因
此我们可以得出这样的一个结论:N!的分解数中有多少个因子就有多少个5,末尾就有多少个0。这样使得外面
的大循环减少五分之四。
//求N!后面零的个数,该方法的外循环需要N/5次

#include<iostream>
using namespace std;
int main()
{
	int i,ii,j,n;
	j=5;
	ii=0;
	cin>>n;
	while(j<=n)
	{
		i=j;
		while(i%5==0)//记录5的倍数
		{
			i=i/5;//拆解5的倍数
			ii=ii+1;//累加
		}
		j+=5;//5的等差数列
	}
	cout<<ii<<endl;
}

方法三:
直接求取5的个数,使用层层剥皮法,先以5为步长,执行一次循环,进行第一次剥皮求出含5的个数(个数为N/5取整),再
以25为步长(因为有的书可以被5整除两次),执行第二次循环,进行第二次剥皮求出25的个数,再以125为步长…直到
步长大于等于N退出循环。例如当N=1000时,写成公式为num=1000/5+1000/(55)+1000/(555)+1000/(5555).[^1]
//求N!后面零的个数,方法3仅需sqrt(N)次循环
分析:该方法的巧妙之处就在于1000/5的得数也包含了1000/25中的一个因数5,这样25这个位置就累加了两次。
所需无需考虑重复使用,反而起到了累加的作用。

#include<iostream>
using namespace std;
int i,ii,n;
int main()
{
	cin>>n;
	i=n;
	ii=0;
	while(i>=5)//迭代求和
	{
		i/=5;
		ii=ii+i;//[^1]累加该公式
	}
	cout<<ii<<endl;
	return 0;
}

总结这三种方法都是建立在2的倍数多余5的前提下的,如果不是全排列则先需要进行判断。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值