题目链接
T 组数据,每组数据输入一个 N,求 Z(N)。
Z(N)是 N 的阶乘的末尾的零的个数。
N<=1e9
根据数据范围可以判定不可以暴力求解,为规律题。
打表找规律,发现
#include#define endl '\n' #define int long long using namespace std; const int N = 2e5 + 10; typedef long long ll;signed main() {ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int t;cin >> t;for (int i = 1; i <= t; i++){int ans = 1;for (int j = 1; j <= i; j++){ans = ans * j;}cout << ans << endl;}return 0; } 1:1 2:2 3:6 4:24 5:120 6:720 7:5040 8:40320 9:362880 10:3628800 11:39916800 12:479001600 13:6227020800 14:87178291200 15:1307674368000 16:20922789888000 17:355687428096000 18:6402373705728000 19:121645100408832000 20:2432902008176640000每 5 个数,末尾增加一个 0,但是不符合样例的输出结果。
从数学角度考虑,提出问题(什么时候才会产生 0?)
已知 10 = 2 * 5
阶乘可以表示为 1 * 2 * 3 * 4 * 5 ··· * n
2 可以用偶数来替代,数量足够多用来凑 10
则需要找到阶乘中 5 的个数,5 为质因数
已知 n / 5 可得 n 中有几个 5 组成(1-n 中是 5 的倍数的个数)
但需要考虑有两个 5 组成的数(25 = 5 * 5)
由此 题目转化为 求 n 的阶乘中 质因数 5 的个数,为答案。
- 暴力不可求解
- 需要考虑 有两个质因数 5 的情况
- 从数学角度分析问题
O(N)O(N)O(N)
- 用 ans 累计质因数 5 的个数
- n / 5 求 n 中 5 的个数,与 2 匹配,成为 10,作为末尾的 0
- 累计 n / 5 的结果继续 / 5,因为其结果仍然包含质因数 5
#include
#define endl '\n'
#define int long long
using namespace std;
const int N = 2e5 + 10;
typedef long long ll;signed main()
{ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int t;cin >> t;while (t--){int n;cin >> n;int ans = 0;while (1){ans += n / 5;n = n / 5;if (n < 5){break;}}cout << ans << endl;}return 0;
}
数学思维好题,需要分析阶乘中末尾零由什么产生。