我正在研究一个非常简单的spoj问题,其中我们必须输入N计算其阶乘然后找出尾随零的数量并显示它像
示例输入:
6
3
60 // 60的事实有14个尾随零
100
1024
23456
8735373
示例输出:
0
14
24
253
5861
2183837
所以我写了一个代码,它在我的机器上工作正常,但是当我提交时它给了我时间限制错误。我不知道如何快速制作这段代码。所以我想要你们的建议。
public class Factorial {
public static void main(String[] args) throws IOException {
try {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
int t = Integer.parseInt(bf.readLine());
for (int i = 0; i < t; i++) {
Long num = Long.parseLong(bf.readLine());
BigInteger bd = BigInteger.valueOf(num);
System.out.println(countTrailinZeros(factorial(bd.toString())));
}
} catch (IllegalStateException e) {
return;
}
}
public static BigInteger factorial(String n) {
BigInteger x = BigInteger.valueOf(1);
for (long i = 1; i <= Integer.parseInt(n); i++) {
x = x.multiply(BigInteger.valueOf(i));
}
return x;
}
public static int countTrailinZeros(BigInteger bd) {
String s = bd.toString();
int glen = s.length();
s = s.replaceAll("[0.]*$", "");
int llen = s.length();
return glen - llen;
}
}
我已经搜索了一些可能的解决方案,并发现查找表可能有用,我对此不太了解。如果有人可以向我解释查询表,我会非常感激。
编辑:可能是java在给定时间内解决这个问题太慢了吗?或者一般来说使用java进行竞争性编程是不利的?
答案 0 :(得分:2)
你不需要计算阶乘以得到尾随零的数量。
解决方案:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int lines = Integer.parseInt(br.readLine());
int sum, N, p;
for (int i = 0; i < lines; i++) {
N = Integer.parseInt(br.readLine());
sum = 0;
p = 5;
while (N / p != 0) {
sum = sum + N / p;
p = p * 5;
}
System.out.println(sum);
}
}
}
逻辑是:
p
中素数N!
的最高幂由
floor(N/p) + floor(N/p*p) + floor(N/p*p*p) ... so on till [floor(N/p^n) = 0]
因此,由于需要结束零的数量,ans = min(max power of 2 in N!, max power of 5 in N!)
因为零乘以十,十分可以分解为10 = (2 * 5)
。
可以假设N的最大功率为5!在N!中总是小于2的最大功率。 因为2的倍数比5的倍数更频繁发生。
因此,问题减少到找到max power of 5 in N!
,从而解决了问题。
示例:
N = 5
max power of 5 in 5! = floor(5/5) + floor(5/25) => 1 + 0 => ans = 1
N = 100
max power of 5 in 100! = floor(100/5) + floor(100/25) + floor(100/125) => 20 + 4 + 0 => ans = 24
答案 1 :(得分:0)
我已经在spoj平台上解决了相同的问题,您只需要将值除以5,直到该值小于5即可。打印除法的所有结果,这就是您的输出。