献上两种方法
方法一:复杂度O(nlog(n))
include
using namespace std;
int T;
void solve()
{
int n;
cin>>n;
int ret=0;
for(int i=1;i<=n;i++)
{
int tmp=i;
while(tmp%5==0)
{
tmp/=5;
ret++;
}
}
cout<<ret<<endl;
}
int main()
{
scanf(“%d”,&T);
for(int step=0;step<T;step++)
{
printf(“case #%d:\n”,step);
solve();
}
return 0;
}
方法二:复杂度O(log(n))
include
using namespace std;
int T;
void solve()
{
int n;
cin>>n;
int ret=0;
int m=5;
while(n>=m)
{
ret+=n/m;
m*=5;
}
cout<<ret<<endl;
}
int main()
{
scanf(“%d”,&T);
for(int step=0;step<T;step++)
{
printf(“case #%d:\n”,step);
solve();
}
return 0;
}
原理:只要找n!这个数能分解为
2^k5^m另一个数
min(k,m) 就是答案
因为可以合成位10^min(k,m)
而k肯定>m,因为2的倍数在n!中很多
只要找5^m*另一个数 这个m
一种方法就是枚举1-n 找每个数中有5的几次方,累加起来
第二种,直接n/5,找1-n中5的倍数有几个
而25这种数,一个数就能贡献两个
因此,第二次n/25,找1-n中25的倍数有几个。
这些数在第一轮已经贡献过一次了,这次只需要每个贡献一个5
再找n/125
以此类推
第二个方法qio棒!