题目描述请参考:ZOJ ACM 2022
1)难点分析
是大数阶乘的延伸。如果要通过计算大数阶乘的方式来计算末尾0的位数,时间效率远远无法满足2秒的要求。
2)解决方法
通过结果的规律来进行运算。设定计算N的阶乘的结果末尾为0的位数。其中N=N*(N-1)*....*i*....*1,尾数为0的尾数为zeroNumber。
首先,只有当i为5的倍数时,i*2必然个位数为0;
其次,当i为5的k次方时,i*(2的k次方) = (5*2)的k次方,所以必然末尾有k个0.由于是阶乘运算,5的k次方,必然可以遇到2的k次方。
通过上述两点基本原理,我们可以有如下结论:
N为5的l倍 ==》 有l个5和2相乘 ==》 有l个10 ==》 zeroNumber = l;
N为5的k次方的m倍 ==》 zeroNumber 增加(k-1)*m。(注意:由于5的二次方是增加了2个0,但是由于前面计算5倍数时,已经增加过一次1,所以后面只需要再加1次即可,以此类推。)
3)AC 源码
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
java.util.Scanner scanner = new java.util.Scanner(System.in);
int lineNum = Integer.parseInt(scanner.nextLine());
for (int lineIndex = 0; lineIndex < lineNum; lineIndex++) {
long n = Long.parseLong(scanner.nextLine());
System.out.println(calc_v2(n));
}
}
public static long calc_v2(long n) {
long zeroNumber = 0;
for(int i=1;i<20;i++) { //这里设置20的原因是,pow(5,20)>题目中N的最大值1000000000,实际设置20还有富余。
long bigNumber = (long)Math.pow(5, i);
zeroNumber+= n / bigNumber;
}
return zeroNumber;
}
}