计算阶乘后缀零的个数

阶乘

时限:1000ms 内存限制:10000K  总时限:3000ms

描述:

给一个整数,请输出该数字阶乘的后缀0的个数,例如:
数字7,它的阶乘为5040,后面有一个0,则输出1;还有数字10,它的阶乘为3628800,后面有两个0,则输出2。

输入:

第一行一个数据N,小于100,表示一共要输入n个数字,以后n行输入一个数字。

输出:

对应于每一个输入,输出一个满足题目要求的数字。

输入样例:

6
3
60
100
1024
23456
8735373

输出样例:

0
14
24
253
5861
2183837



 

提示:

 

来源:

2006西北工业大学程序设计竞赛初赛题A

这个问题并不难,关键的一点是要知道一个特点(本人初学,说错了请指正)

这个特点就是:

1*2*3*4*.....*n可以写成1*2*3*(2*2)*5*(2*3)*7*(2*2*2)*............

求n!后缀零有多少个实际上就是求上式有多少个10因子,也就是求有多少2*5的问题,而明显2的个数多余5,因此就转换成了求5的个数,这个问题可以用以下代码实现:

int i,count5=0;

for(i=5;i<=n;i*=5)

     count5+=n/i;

下面是这个结论的证明,是我在网上转载的:

结论1: 对于n的阶乘n!,其因式分解中,如果存在一个因子“5”,那么它必然对应着n!末尾的一个“0”。
下面对这个结论进行证明:
(1)当n < 5时, 结论显然成立。
(2)当n >= 5时,令n!= [5k * 5(k-1) * ... * 10 * 5] * a,其中 n = 5k + r (0 <= r <= 4),a是一个不含因子“5”的整数。
对于序列5k, 5(k-1), ..., 10, 5中每一个数5i(1 <= i <= k),都含有因子“5”,并且在区间(5(i-1),5i)(1 <= i <= k)内存在偶数,也就是说,a中存在一个因子“2”与5i相对应。即,这里的k个因子“5”与n!末尾的k个“0”一一对应。
我们进一步把n!表示为:n!= 5^k * k! * a(公式1),其中5^k表示5的k次方。很容易利用(1)和迭代法,得出结论1。

上面证明了n的阶乘n!末尾的“0”与n!的因式分解中的因子“5”是一一对应的。也就是说,计算n的阶乘n!末尾的“0”的个数,可以转换为计算其因式分解中“5”的个数。

令f(x)表示正整数x末尾所含有的“0”的个数, g(x)表示正整数x的因式分解中因子“5”的个数,则利用上面的的结论1和公式1有:
   f(n!) = g(n!) = g(5^k * k! * a) = k + g(k!) = k + f(k!)
所以,最终的计算公式为:
当0 < n < 5时,f(n!) = 0;
当n >= 5时,f(n!) = k + f(k!), 其中 k = n / 5(取整)。

这样这个问题就解决了,源代码如下:

    • #include<stdio.h>
    • #include<malloc.h>
    •  
    • int iCount(int);
    •  
    • int main()
    • {
    •     int n,*a=NULL,i;
    •     scanf("%d",&n);
    •     a=(int *)malloc(sizeof(int)*n);
    •     for(i=0;i<n;i++)
    •     {
    •         scanf("%d",&a[i]);
    •         printf("%d/n",iCount(a[i]));
    •     }
    •     free(a);
    •     return 0;
    • }
    • int iCount(int n)
    • {
    •     int count5=0;
    •     int i;
    •     for(i=5;i<=n;i*=5)
    •         count5+=n/i;
    •     return count5;
    • }
    •  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值