阶乘末尾零的数目

阶乘末尾零的数目

题目描述

给定一个非负整数N,返回N!结果的末尾为0的数量

输入描述:

第一行一个整数N。

输出描述:

输出一个整数表示N!的末尾0的数量。

示例1
输入
3
输出
0
说明
3! = 6
示例2
输入
5
输出
1
说明
5! = 120
示例3
输入
1000000000
输出
249999998
备注:

1 ⩽ N ⩽ 1 0 18 1 \leqslant N \leqslant 10^{18} 1N1018


解法一:

阶乘的末尾有多少个 0 ,跟因子 2 和 5 有关,而在 1 ∗ 2 ∗ 3 ∗ . . ∗ n 1*2*3*..*n 123..n 中,因子 2 的数目要多于因子 5 的数目,所以只需要统计 1~n 中多少个因子 5 即可。如果直接遍历 1~n ,统计每个数的因子 5 数目,则时间复杂度 O ( n l o g 5 n ) O(nlog_5^{n}) O(nlog5n)

解法二:

假设 n 为 125,则我们会发现:

  1. 5、10、15、20、25、…、125,含一个因子 5
  2. 25、50、75、100、125,含两个因子 5
  3. 125,含三个因子 5

通过上面可以发现,n! 中的因子 5 的总个数为:

n / 5 + n / ( 5 2 ) + n / ( 5 3 ) + . . . + n / ( 5 i ) n/5 + n/(5^2) + n/(5^3) + ... + n/(5^i) n/5+n/(52)+n/(53)+...+n/(5i)

一直到 5 i > n {5^i} > n 5i>n 停止。时间复杂度 O ( l o g 5 n ) O(log_5^{n}) O(log5n)

解法二代码:
#include <cstdio>

using namespace std;

typedef long long LL;

int main(void) {
    LL n;
    scanf("%lld", &n);
    LL ret = 0;
    while ( n ) {
        ret += n / 5;
        n /= 5;
    }
    return 0 * printf("%lld\n", ret);
}
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页