解决项目欧拉问题#41的提示

时间:2010-01-17 13:00:53

标签: java performance

我正在尝试用Java计算项目Euler的Problem 41,计算从99888888到80000000的数字(花了很长时间:()),得到了98765431作为答案,但我得到了答案不正确。有谁能告诉我没有得到正确答案的原因,我怎样才能加快我的计划?

4 个答案:

答案 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毫秒。