7-1 阶乘末尾0的个数

从输入中读取一个数n,求出n!中末尾0的个数。

输入格式:

输入有若干行。第一行上有一个整数m,指明接下来的数字的个数。然后是m行,每一行包含一个确定的正整数n,1<=n<=1000000000。

输出格式:

对输入行中的每一个数据n,输出一行,其内容是n!中末尾0的个数。

输入样例:

3
3
100
1024

输出样例:

0
24
253

代码长度限制

16 KB

时间限制

1000 ms

内存限制

64 MB

解题思路: 

首先要明白阶乘函数的递增速度是极快的。从10!开始就有爆炸式的增长。

10!=3 628 800;而11!=39 916 800 ; 12!=479 001 600 13!=6 227 020 800(10位数字)

而int 数据类型的取值范围为-2147483648~2 147 483 647(10位数字)

很明显,从13!开始,具体结果已经不能用int表示了。

所以用int数据类型计算阶乘,最多可以计算到12!。

下面说用long long数据类型计算。

首先要知道long long数据类型的取值范围为

-9223372036854775808~9 223 372 036 854 775 807(19位数字)

20!=2 432 902 008 176 640 000(19位数字)

21!=5.1090942171709e+19 大于long long数据类型的取值范围

很明显从21!开始,具体结果已经不能用long long数据类型表示了。

int 数据类型 long long数据类型分别可以算到的阶乘为十二的阶乘 二十阶乘(十二 二十,刚好便于记忆。)

但是这道题。最大值却是1000000000,明显不是让我们算出阶乘再统计。

再想想,末尾有多少个0,意味着要乘以多少个10,10又等于多少呢?10可以写为2*5。

再所以我们要统计有多少个2*5

很明显我们知道,2为因数的数明显多余5为因数的数,因此我们只要统计有多少个5相乘,因此循环求解就行,我们任意给定一个数,比如说25,里边有5=1*5 10=2*5 15=3*5 20=4*5 25=5*5

可以看出有6个5相乘。

当然我们可以循环统计从最高位逐个递减,看每个数能被5整除几次,加起来即可。但是需要多一层循环。有没有更简单的策略呢?

我们发现,任何数除以五,就相当于它下面有多少个5的倍数,如25/5=5,说明他下面有5个5的倍数5,10,15,20,25。但是25/5=5.。任然是5的倍数,说明可以分为两个5相乘,所以25/(5*5)=1,说明有1个5*5,依此类推,可以算出1个5的,2个5的,3个5的。

代码如下(借鉴于

zlzhujust

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n,m;
	cin>>m;
	while(m--){
		cin>>n;
		int t=5,cnt=0;
		while(t<=n){
			cnt+=n/t;  //统计5的个数 
			t*=5;  //一些数可以不止一次除以5 
		}
		cout<<cnt<<endl;
	}
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值