我正在尝试用Java计算项目Euler的Problem 41,计算从99888888到80000000的数字(花了很长时间:()),得到了98765431作为答案,但我得到了答案不正确。有谁能告诉我没有得到正确答案的原因,我怎样才能加快我的计划?
答案 0 :(得分:9)
pandigital数字不需要包含1 to 9
中的所有数字,而是来自1 to length
的所有数字。
所以,你需要尝试1 to 9
的所有排列,从1位开始,然后上升,过滤所有素数,然后取最大值。
答案 1 :(得分:5)
在合理的"中获得解决方案。时间,你需要根据特殊属性进行以下观察:如果数字的总和可以被3整除,则数字可被3整除:
divisible by
1+2+3+4 = 10 -
1+2+3+4+5 = 15 3
1+2+3+4+5+6 = 21 3
1+2+3+4+5+6+7 = 28 -
1+2+3+4+5+6+7+8 = 36 3
1+2+3+4+5+6+7+8+9 = 45 3
所以,一个"大" prime pandigital数字 4或7位。 (大于3的素数不能被3整除)
因为您想获得最大数字,所以最好从7位数字开始,并且只有在找不到数字的情况下才继续检查4位数字。当然,存在一个4位数字,因为它被指定为:2143
。
现在,一个可能的解决方案如下:
public class P41 {
public static void main(String[] args) {
boolean wasFound = false;
for (int nr = 7654321; nr >= 1234567; nr -= 2) { // even != prime
if (isPandigital(nr) && isOddPrime(nr)) {
System.out.println(nr);
wasFound = true;
break;
}
}
if (!wasFound) {
/* not <=, because 1234 is even */
for (int nr = 4321; nr > 1234; nr -= 2) {
if (isPandigital(nr) && isOddPrime(nr)) {
System.out.println(nr);
break;
}
}
}
}
private static boolean isOddPrime(int x) {
int sqrt = (int) Math.sqrt(x);
for (int i = 3; i <= sqrt; i += 2) {
if (x % i == 0) {
return false;
}
}
return true;
}
private static int getNumberOfDigits(int x) {
int count = 0;
while (x > 0) {
count++;
x /= 10;
}
return count;
}
private static boolean isPandigital(int x) {
int numberOfDigits = getNumberOfDigits(x);
Set<Integer> digits = new HashSet<Integer>();
for (int i = 1; i <= numberOfDigits; i++) {
digits.add(i);
}
for (int i = 1; i <= numberOfDigits; i++) {
digits.remove(x % 10);
x /= 10;
}
if (digits.size() == 0) {
return true;
} else {
return false;
}
}
}
时间: 8 ms 。
答案 2 :(得分:4)
唯一可能的主要数字数字是长度 1,4和&amp; 7因为每隔一个pandigital数字的总和都可被3整除。
因此,您只需要测试7! = 5040
排列。
答案 3 :(得分:0)
以下是问题陈述:
如果它使用所有数字1到n恰好一次,我们将说n位数是pandigital。例如,2143是一个4位数的pandigital,也是素数。存在的最大n位数pandigital素数是什么?
我写了一个以987654321开头并倒计时的程序。我检查过这个数字是pandigital,如果是,检查它是不是素数。
我的Windows 8.1计算机花了66秒才找到最大的素数。
当我测试相反的方式,首先是素数,然后是pandigital,程序的持续时间超过66秒。我取消了它。
当我申请GregS&#39;关于折扣所有9位数字和8位数字数字的数据,并从7654321开始倒计时,我的强力算法需要13毫秒。