题意:
You task is to find minimal natural number \(N\), so that \(N!\) contains exactly \(Q\) zeroes on the trail in decimal notation. As you know \(N! = 1*2*...*N\).For example, \(5! = 120\), \(120\) contains one zero on the trail.
数据范围:\(T ≤ 10^4,1 ≤ Q ≤ 10^8\)
分析:
关键在于给定一个数 \(n\),如何求出 \(n!\)有多少个 \(5\)。
一开始想维护一个前缀和,来纪录 \(n!\) 的因子中有多少个 \(5\)。但是时间和空间的花费太多了。
这里介绍一个定理:
令 \(f(x)\) 表示 \(x!\) 中因子 \(5\) 的个数;
\[f(n!)=\begin{cases} 0 & n<5\\ k+f(k!) & k=\frac{n}{5} \end{cases}\]
推广到任意数 \(x\),有
\[f(n!)=\begin{cases} 0 & n<x\\ k+f(k!) & k=\frac{n}{x} \end{cases}\]
求阶乘,数肯定是连续的。那么先除 \(x\),就把 \([1,n]\) 中含有至少一个因子 \(x\) 的数的个数求出,再使 \(n/x\)。然后依次类推。
知道这个之后,我们直接二分就可以求出答案。
代码:
#include <bits/stdc++.h>
using namespace std;
const int N=4e8+100;
int solve(int n)
{
int res=0;
while(n)
{
res+=n/5;
n/=5;
}
return res;
}
int main()
{
int t,q,cot=0;
scanf("%d",&t);
while(t--)
{
scanf("%d",&q);
int l=4,r=N;
while(l<=r)
{
int mid=(l+r)>>1;
if(solve(mid)>=q)
r=mid-1;
else
l=mid+1;
}
printf("Case %d: ",++cot);
if(solve(l)==q)
printf("%d\n",l);
else
printf("impossible\n");
}
return 0;
}