此题n的取值可能很大,甚至会达到亿,这里我们区最大范围2000000000(2*10^9)。
分析一:
乘积末尾的0的个数依赖于因子中的2的个数和5的个数。对于阶乘来说,每2个数字就至少有一个2的因子,所以2的因子是足够的。5的因子相对少些,至少连续5个数才能保证一定出现一个。注意,这里连续5个书保证出现一个5的因子是指最少的情况。比如1,2,3,4,5,这就只会出现一个。但是考虑 21,22,23,24,25,25 = 5 * 5,所以如果乘以25那就能得到2个5的因子。
为了解决这个问题,必须首先从数学上分析在N!结果值的末尾产生零的条件。不难看出:一个整数若含有一个因子5,则必然会在求N!时产生一个零。因此问题转化为求1到N这N个整数中包含了多少个因子5。若整数N能被25整除,则N包含2个因子5;若整数N能被5整除,则N包含1 个因子5。这样可实现一下代码:#include<iostream> using namespace std; int main() { int num,i; long long n,m,count_5num; cin>>num; for(i=0;i<num;i++) { cin>>n; count_5num=0; while(n%5!=0)n--; while(n>0) { m=n; while(m%5==0) { count_5num++; m/=5; } n-=5; } cout<<count_5num<<endl; } return 0; }
但是这个代码的缺点是,n极大,那么运行时间很长,
如运算2*10^8,可能需要五秒
运算2*10^9甚至需要几十秒
为此我做了如下改进:
分析二:
1、算出所有小于等于n且能被5整除的整数的个数------[n/5]
2、算出所有小于等于n且能被25整除的整数的个数-----[n/25]3、算出所有小于等于n且能被125整除的整数的个数----[n/125]...................
.................
...................
算出所有小于等于n且能被5^x整除的整数的个数--------[n/5^x](其中,5^x为小于等于n的5的最大次方)
这样,我们就能快速地算出行数字5这个因子的最大个数了
优化后的代码:
#include<iostream> using namespace std; int main() { int num,i,count_5num; long long n,m; cin>>num; for(i=0;i<num;i++) { cin>>n; count_5num=0; for(m=5;m<=n;m*=5) count_5num+=(int)(n/m); cout<<count_5num<<endl; } return 0; }
上述优化后的代码可使运算速度增大不少,运算2*10^9只需一秒不到注意:m,n,count_5num的类型要取long long型,long型都不可以,否则可能会出现count_5num累加反而会减小的情况。