题意: 给一个数n,返回其阶乘结果后缀有几个0。
思路:
首先将n个十进制数进行质因数分解,观察的得到只有2*5才会出现10。那么n!应含有min(2个数,5个数)个后缀0,明显5的个数必定比2少,所以后缀0的个数为质因数后的5的个数。
为何这么说?例如n=15,那么{1 2 3 4 5 6 7 8 9 10 11 12 13 14 15},那么可以产生2的数字有{2,4,6,8,10,12,14},可以产生5的只有{5,10,15},质数中只有2乘以5才能形成10,那么min(2个数,5个数)就决定了可以产生10的个数,也就决定了产生的0的个数。
想将[1,n]逐个进行质因数分解来取统计5的个数?不用,有更简单的方法。
假设n=15,将n/5得到3,则[1,15]中有3个是5的倍数即{5,10,15},只有是5的倍数才能产生质因数5,那么count+=3。接着,这3个数字可能还很大,除以5之后也许还能继续被5除(例如25就可以除两次)。然而{5,10,15}除完之后变成了{1,2,3},这个序列一定是连续的自然数,由于全都小于5,那肯定是没能再有5的产生了。假如n/5大于5呢?那么[1,n]中的5的倍数肯定会变成[1,n/5],又是一个阶乘的形式,继续用上面的方法继续拆出所有的5,直到n/5/5/5...的结果小于5为止。每次n/5之后的数就是count的结果。
1 #include <bits/stdc++.h> 2 #define LL long long 3 using namespace std; 4 int f(unsigned int n) 5 { 6 if (n < 5) { 7 return 0; 8 } 9 return n / 5 + f(n / 5); 10 } 11 12 int main() 13 { 14 //freopen("input.txt", "r", stdin); 15 unsigned int t, a; 16 cin>>t; 17 while(t--) 18 { 19 scanf("%d",&a); 20 printf("%d ",f(a)); 21 } 22 23 return 0; 24 }