c语言实现求100(n)的阶乘尾部有多少连续的0
100的阶乘尾部求0个数
我们知道c语言是无法直接存储100的阶乘的,其实从17开始已经溢出,34开始之后都是0。所以这其实是一道数数问题。
首先,搞清楚原理。
两数相乘怎样才能产生0,很明显只要是一个偶数与5相乘就会产生1个0。因为在1到100中偶数明显比5多,那么只用考虑1到100有多少个5就可以了。
先来看5的倍数的情况
2 * 5 = 10
4 * 10 = 40 → 4 * 2 * 5 = 40
6 * 15 = 80 → 6 * 3 * 5 = 80
也就是说当5和5的倍数出现时就会产生一个0.但是当25出现时,情况不同了,因为25 = 5 * 5,此时出现了两个5,那么总能找到一个偶数与其相乘得到两个0。
如 12 * 25 = 300
同样25的倍数与偶数相乘也会出现2个0.那么把25看成52 .因为53已经超出100,所以只用考虑25及其倍数。
如此已经可以用代码实现了,只要n%5为0,计数器+1,同时n%25为0,计数器再+1(25及其倍数本身就是5的倍数,所以只用+1次)
int i,cnt;
cnt=0;
for(i=1;i<101;++i){
if(!(i%5)){
cnt++;
if(!(i%25)){
cnt++;
}
}
}
printf("100的阶乘尾部有%d个0.\n",cnt);
运行结果
但是,这段代码一股翔味显得过于累赘,当我们了解原理后,一行代码就可以实现。
printf("100的阶乘尾部有%d个0.\n",100/5+100/25);
n的阶乘尾部求0个数
基于以上实现求100阶乘尾部0个个数,求任意n的阶乘尾部0的个数就很容易了,只要把5的次幂全部考虑在内就可以,此处只实现n为整型。
int i=5,sum=0,x;
printf("input:\n");
scanf("%d",&x);
for(;i>0;i*=5){
if((x>=i)&&(x<i*5)){
for(int j=5;j<=i;j*=5){
sum+=x/j;
}
break;
}
}
printf("%d\n",sum);
以上代码是将n划为[5,25),[25,125)……的区间求和,防止越界,最外层循环加入了i>0的条件。break减少运算次数。
运行结果
当然也有一行代码实现,小于231-1的最大5的次幂是513 = 1220703125,所以如下
printf("%d",x/5+x/25+x/125+x/625+x/3125+x/15625+x/78125+x/390625+x/1953125+x/9765625+x/48828125+x/244140625+x/1220703125);