免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
1234下一页
最近访问板块 发新帖
查看: 17627 | 回复: 33
打印 上一主题 下一主题

计算阶乘n!末尾所含0的个数 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-04-21 16:25 |只看该作者 |倒序浏览
------------------------------------------------------------------------
今天整理资料时发现了一段有趣的笔记,稍加整理,贴上来作个标签吧
期待数学达人能用更严格的数学形式证明
-------------------------------------------------------------------------

问题描述
    给定参数n(n为正整数),请计算n的阶乘n!末尾所含有“0”的个数。
    例如,5!=120,其末尾所含有的“0”的个数为1;10!= 3628800,其末尾所含有的“0”的个数为2;20!= 2432902008176640000,其末尾所含有的“0”的个数为4。

计算公式
    这里先给出其计算公式,后面给出推导过程。
    令f(x)表示正整数x末尾所含有的“0”的个数,则有:
      当0 < n < 5时,f(n!) = 0;
      当n >= 5时,f(n!) = k + f(k!), 其中 k = n / 5(取整)。

问题分析
    显然,对于阶乘这个大数,我们不可能将其结果计算出来,再统计其末尾所含有的“0”的个数。所以必须从其数字特征进行分析。下面我们从因式分解的角度切入分析。

    我们先考虑一般的情形。对于任意一个正整数,若对其进行因式分解,那么其末尾的“0”必可以分解为2*5。在这里,每一个“0”必然和一个因子“5”相对应。但请注意,一个数的因式分解中因子“5”不一定对应着一个“0”,因为还需要一个因子“2”,才能实现其一一对应。

    我们再回到原先的问题。这里先给出一个结论:
    结论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(取整)。

计算举例
   f(5!) = 1 + f(1!) = 1
   f(10!) = 2 + f(2!) = 2
   f(20!) = 4 + f(4!) = 4
   f(100!) = 20 + f(20!) = 20 + 4 + f(4!) = 24
   f(1000!) = 200 + f(200!) = 200 + 40 + f(40!) = 240 + 8 + f(8!) = 248 + 1 + f(1) =249
   ...

终于写完了,困S了:)

论坛徽章:
0
2 [报告]
发表于 2007-04-21 16:35 |只看该作者
也算递归吧

论坛徽章:
0
3 [报告]
发表于 2007-04-21 16:43 |只看该作者
Pot_p(n!) = [n/p] + Pot_p([n/p]!)

递归使用这个公式就可以得到 Pot_p(n!) 的表达式。

可以参考柯召,孙琦的 《数论讲义》上册,数论函数部分。

论坛徽章:
0
4 [报告]
发表于 2007-04-21 16:48 |只看该作者
原帖由 win_hate 于 2007-4-21 16:43 发表
Pot_p(n!) = [n/p] + Pot_p([n/p]!)

递归使用这个公式就可以得到 Pot_p(n!) 的表达式。

可以参考柯召,孙琦的 《数论讲义》上册,数论函数部分。

恩,我上面推出的公式就是这个,p为5吧?
哎,又吃了数字的亏了
手头没这本书,看能不能找到

论坛徽章:
0
5 [报告]
发表于 2007-04-21 16:53 |只看该作者
我去年去学校招聘的时候,给应届生出了这个题目,只有2个人的想法靠近这个答案。

论坛徽章:
0
6 [报告]
发表于 2007-04-21 16:54 |只看该作者
原帖由 tyc611 于 2007-4-21 16:48 发表

恩,我上面推出的公式就是这个,p为5吧?
哎,又吃了数字的亏了
手头没这本书,看能不能找到


是的。


我以前写过一个资料,复制到这里吧:

......
另一很精致的方法来自柯召的 “数论讲义”,把 ord_p 简记为 ord:

    * ord(ab)=ord(a)+ord(b)
      
    * ord(n!) = [n/p] + ord( [n/p]! ),因为:
      ord(n!)
      = ord(1) + ... + ord(n)
      = ord(p) + ord(2p) + ... + ord([n/p]p)
      = (ord(1) + ord(p)) + (ord(2)+ord(p)) + ... + (ord([n/p])+ord(p))
      = (ord(1) +1) +(ord(2)+1) +...+(ord([n/p])+1)
      = [n/p]+ord( [n/p]! )

    *  [ [n/p]/p ] = [n/p^2]
      若把 n 写成 p 进制表达,则上面这个式子很好理解

现在只要递归地调用 ord(n!) = [n/p] + ord( [n/p]! ) 就可以得到 ord(n!) 的表达式:

[n/p]+[n/p^2]+[n/p^3] +....

论坛徽章:
0
7 [报告]
发表于 2007-04-21 18:23 |只看该作者
赞排版。

论坛徽章:
0
8 [报告]
发表于 2007-04-21 19:42 |只看该作者
一个和此问题有点关系的有趣问题是:
给定质数p, 求杨辉三角第n行有多少个元素被p整除.

论坛徽章:
0
9 [报告]
发表于 2007-04-21 22:18 |只看该作者
原帖由 ArXoR 于 2007-4-21 19:42 发表
一个和此问题有点关系的有趣问题是:
给定质数p, 求杨辉三角第n行有多少个元素被p整除.


嗯,柯召那本书的 pot 一节最后一个定理就是求 pot_p ( binomial(n, r) )  的表达式.

论坛徽章:
0
10 [报告]
发表于 2007-04-21 22:49 |只看该作者
原帖由 win_hate 于 4/21/07 22:18 发表


嗯,柯召那本书的 pot 一节最后一个定理就是求 pot_p ( binomial(n, r) )  的表达式.


pot_p ( binomial(n, r) ) 有close from? 我只知道级数表达的形式.
不过不妨碍我说的这个问题的解决, 呵呵.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP