计算n的阶乘有多少个尾随零

思路一:

计算出n!= nValue,然后 nValue % 10 == 0 则nCount自增1,nValue /= 10 直到条件为否,最后nCount就是我们想要的结果,代码如下:

 1 int CountZero(int n)
 2 {
 3     unsign long long nValue = 1;
 4     for (int i = 2; i <= n; i ++)
 5     {
 6         nValue *=i;
 7     }
 8     int nCount = 0;
 9     while(0 == nValue % 10)
10     {
11         nCount ++;
12         nValue /= 10;
13     }
14     return nCount;
15 }

代码简洁易懂,看上去还不赖,但是这里要考虑一个问题就是在求n!整数溢出了怎么办?  显然我们使用_int64也同样会有溢出的时候,所以上面的代码实际上是不可行的。

思路二:

不知道怎么办,不妨先举例分析:

1! = 1
2! = 1 * 2 = 2
3! = 1 * 2 *3 = 6
4! = 1 * 2 * 3 * 4 = 24
5! = 1 * 2 * 3 * 4 * 5 = 120
........
1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13
* 14 * 15 * 16 * 17 * 18 * 19 * 20 * 21 * 22 *23 * 24 * 25

我们会发现一个因子2和因子5组合产生一个0,这样我们只需统计1到n有多少个因子对,即n!的尾随零个数,因子2的个数比因子5的个数多,因此我们只需统计出因子5的个数即可,如

5,10,15,25,30,35,40.......

需要注意的是,以100!为例:

统计一次5的倍数 (5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100)= 20

统计一次25的倍数(因为25的倍数有两个5的因子,所以再统计一次)(25,50,75,100) = 4

统计一次125的倍数(125的倍数由3个5的因子,所以再统计一次,以此类推)(nil)

所以100!的尾随零个数为24个

实现代码如下:

1 int CountZero(int n)
2 {
3     int count = 0;
4     if (n < 0)
5         return -1;
6     for (int i = 5; n / i > 0; i *= 5)
7         count += n / i;
8     return count;
9 }
运行结果:
1 1 0 0
2 2 0 0
3 6 0 0
4 24 0 0
5 120 1 1
6 720 1 1
7 5040 1 1
8 40320 1 1
9 362880 1 1
10 3628800 2 2
11 39916800 2 2
12 479001600 2 2
13 6227020800 2 2
14 87178291200 2 2
15 1307674368000 3 3
16 20922789888000 3 3
17 355687428096000 3 3
18 6402373705728000 3 3
19 121645100408832000 3 3
20 2432902008176640000 4 4
21 14197454024290336768 0 4
22 17196083355034583040 1 4
23 8128291617894825984 0 4
24 10611558092380307456 0 4

当n=21时,21!已经溢出。

时间: 2024-08-28 22:29:42

计算n的阶乘有多少个尾随零的相关文章

题目二:计算5的阶乘 5!的结果是?

//计算5的阶乘 5!的结果是? int i ; int s=1; for(i=1;i<=5;i++) { s=s*i; } System.out.println(s);

35.按要求编写Java程序: (1)编写一个接口:InterfaceA,只含有一个方法int method(int n); (2)编写一个类:ClassA来实现接口InterfaceA,实现int method(int n)接口方 法时,要求计算1到n的和; (3)编写另一个类:ClassB来实现接口InterfaceA,实现int method(int n)接口 方法时,要求计算n的阶乘(n

  35.按要求编写Java程序: (1)编写一个接口:InterfaceA,只含有一个方法int method(int n): (2)编写一个类:ClassA来实现接口InterfaceA,实现int method(int n)接口方 法时,要求计算1到n的和: (3)编写另一个类:ClassB来实现接口InterfaceA,实现int method(int n)接口 方法时,要求计算n的阶乘(n!): (4)编写测试类E,在测试类E的main方法中使用接口回调的形式来测试实现 接口的类. p

计算n的阶乘(n!)末尾0的个数

题目: 给定一个正整数n,请计算n的阶乘n!末尾所含有“0”的个数. 举例: 5!=120,其末尾所含有的“0”的个数为1: 10!= 3628800,其末尾所含有的“0”的个数为2: 20!= 2432902008176640000,其末尾所含有的“0”的个数为4 解题思路: 两个大数字相乘,都可以拆分成多个质数相乘,而质数相乘结果尾数为0的,只可能是2*5.如果想到了这一点,那么就可以进一步想到:两个数相乘尾数0的个数其实就是依赖于2和5因子的个数.又因为每两个连续数字就会有一个因子2,个数

shell脚本,通过一个shell程序计算n的阶乘。

[[email protected] ~]# cat jiechen.sh #!/bin/bash #设计一个shell程序计算n的阶乘,要求: #1.从命令行接收参数n; #2.在程序开始后立即判断n的合法性,即是否有参数,若有是否为正整数,若非法请给错误提示. #3.最后出计算的结果 num=$1 expr $num + 1 &>/dev/null [ $? -ne 0 ] && echo "please input a number." &&

POJ 1401 &amp;&amp; ZOJ 2202 Factorial 阶乘N!的末尾零的个数

POJ 1401 && ZOJ 2202 Factorial 阶乘N!的末尾零的个数 题目地址: POJ 1401 ZOJ 2202 题意: 求N!后面有几个0. 分析: 组合数学类型的题目. 正常的话可能会去分解1~N数里面有几个5和2,但是这样的复杂度为O(nlogn). 其实有更巧妙的办法,可以把问题分解成子问题. 可以发现N!末尾的0与1~N中有几个5的因子相同(因为2总是比5多). 1~N中只有5的倍数包含5因子,比如[5, 10, 15, 20...],所以我们抽出其中每个数的

计算1024的阶乘 python3

Programing language : python3 方案一 1 #! /usr/bin/env python 2 # -*- coding:utf-8 -*- 3 # 计算1024的阶乘 4 factorial = 1 5 for i in range(1, 1024 + 1): 6 factorial = factorial * i 7 print("1024! =", factorial)  方案二 1 #! /usr/bin/env python 2 # -*- codi

输入一个正数x和一个正整数n,求下列算式的值。要求定义两个调用函数:fact(n)计算n的阶乘;mypow(x,n)计算x的n次幂(即xn),两个函数的返回值类型是double

题目描述 输入一个正数x和一个正整数n,求下列算式的值.要求定义两个调用函数:fact(n)计算n的阶乘:mypow(x,n)计算x的n次幂(即xn),两个函数的返回值类型是double. x - x2/2! + x3/3! + ... + (-1)n-1xn/n! ×输出保留4位小数. 输入 x n 输出 数列和 样例输入 2.0 3 样例输出 1.3333 提示 无 来源 无 1 #include<stdio.h> 2 double fact(int); 3 double mypow(in

利用c语言计算n的阶乘及其求和(多种方法)

计算某一个数的阶乘: #include <stdio.h> int main() { int n,i; scanf("%d",&n); for(i=n-1;i>0;i--) { n=n*i; } printf("%d",n); return 0; } 计算1!+2!+3!+...+10! #include <stdio.h> int  main() { int a,b,c; int sum=0; for(a=1;a<=10

Linux下汇编语言------计算n的阶乘

用高级语言比方C语言写个阶乘非常easy,那如今就来熟悉下Linux使用AT&T汇编格式写一个程序来计算阶乘吧 写法一是 使用跳转指令实现.写法二是使用函数来实现 约定:本程序没有将结果打印在标准输出上. 须要使用GDB调试查看 写法一 #as filename.s -o filename.o #ld filename.o -o filename # gdb filename .section .data .section .text .globl _start _start: movl $1,