题目描述
10000的阶乘是一个很大的数字,但这一次我们关心的不是这个数字是多少,而是这个数字从个位开始向左直到第一个不为零的数字一共有多少个零。比如5的阶乘是120。有1个零,10的阶乘是3628800,有2个零。现给你若干个数,这些数各有多少个零。
输入格式
第一行为数N,表示有多少个数
此后一行一个整数(数的范围为1至1000000000)
输出格式
对每一个整数,输出该数阶乘中按题意要求的需的个数
输入样例
6
3
60
100
1024
23456
8735373
输出样例
0
14
24
253
5861
2183837
题目分析
一般方法:
先计算阶乘,在从个位向左依次判断是否为0,遇到0加一,否则结束循环
优点:逻辑简单
缺点:计算时间长,不适合大数据(说人话就是数据存不下,提交会超时)
优化方案:
末尾为0与质因数5有关,2*5=10,5和2成一对则有一个0,而在阶乘中遇到5的倍数,它的前一个数一定是偶数,即可以认为遇到5的倍数末尾就出现0;
又25*4=100,即出现25的倍数末尾就会有2个0,同理遇到125的倍数就会有3个0;
举例说明:
假设要求125!末尾0的个数
先125/5=25,这里的25表示从1到125一共有25个5的倍数,所以末尾至少有25个0
再25/5=5,这里的5(商)表示从1到125有5个25(因为125先后除以了两个5,相当于除以了25,下同)的倍数,所以在原来25个0的基础上还要加上5个0,即30个0;
再5/5=1;这里的1表示从1到125有1个125(同上,不再解释)的倍数,所以在原来30个0的基础上加上一个,即31个0
由于1/5=0,不会再出现0,则循环终止,故循环结束条件为此。
优点:不用计算阶乘,计算时间短,可计算数据更大
缺点:需要分析,逻辑较为复杂
#include <stdio.h>
int main()
{
int n,x,sum;
scanf("%d",&n);
for(int i=0;i<n;++i)
{
sum=0;
scanf("%d",&x);
for(;x!=0;x/=5)
sum+=x/5;
printf("%d\n",sum);
}
return 0;
}