阶乘末尾零的数目
题目描述
给定一个非负整数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} 1⩽N⩽1018
解法一:
阶乘的末尾有多少个 0 ,跟因子 2 和 5 有关,而在 1 ∗ 2 ∗ 3 ∗ . . ∗ n 1*2*3*..*n 1∗2∗3∗..∗n 中,因子 2 的数目要多于因子 5 的数目,所以只需要统计 1~n 中多少个因子 5 即可。如果直接遍历 1~n ,统计每个数的因子 5 数目,则时间复杂度 O ( n l o g 5 n ) O(nlog_5^{n}) O(nlog5n)。
解法二:
假设 n 为 125,则我们会发现:
- 5、10、15、20、25、…、125,含一个因子 5
- 25、50、75、100、125,含两个因子 5
- 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);
}