项目欧拉97

时间:2013-12-18 20:01:20

标签: java

我正在尝试解决Project Euler#97问题。我不想在网上看,因为他们直接提供解决方案。

这是练习:

  

发现超过一百万位数的第一个已知素数是   1999年发现,并且是梅森素数的形式2 ^ 6972593-1;   它包含正好2,098,960位数字。随后其他梅森   已找到包含更多数字的2 ^ p-1形式的素数。

     

然而,在2004年发现了一个巨大的非梅森素数   包含2,357,207位数:28433×2 ^ 7830457 + 1.

     

找到此素数的最后十位数。

所以,我试过这个:

public static void main(String []args){ 
        BigInteger i = new BigInteger("28433")
                          .multiply(new BigInteger(String.valueOf(Math.pow(2, 7830457)))
                          .add(new BigInteger("1")));

        String s = i.toString();
        System.out.println(s.substring(s.length()-10, s.length()));
     }

显然这不起作用:

Exception in thread "main" java.lang.NumberFormatException: For input string: "Infinity"

我应该如何解决这个问题(我真的被困住了)? (请不要给出解决方案,只是提示)

由于

3 个答案:

答案 0 :(得分:6)

你有一个问题,你想要答案mod 10 ^ 10(最后十位数)

您可以使用2的幂来更快地计算功率。例如x * x = x ^ 2,并且x ^ 2 * x ^ 2 = x ^ 4等等。 7 830 457 = 0b11101110111101110111001是2 ^ 23 + 2 ^ 22 + 2 ^ 21 + 2 ^ 19 ... 2 ^ 0所以它是x ^(2 ^ 23)* x ^(2 ^ 22)* x(2 ^ 21)* x ^(2 ^ 19)* ... x你必须执行每个操作mod 10 ^ 10以避免溢出。你可以将它乘以第一个常数并加1。

使用这种方法,您可以在O(log N)中计算,其中N是幂。

将为您完成大部分工作的关键功能是BigInteger.modPow它旨在有效地计算大功率,但仅计算数字的最低部分(基于所选的模型)

答案 1 :(得分:0)

问题在于计算2 ^ 7830457

他们想要最后10位数,这意味着数字mod 10000000000

根据这个:http://en.wikipedia.org/wiki/Modulo_operation

ab mod n =((mod n)*(b mod n))mod n

所以你可以在一个循环中使用乘法计算2 ^ 7830457,你在每次乘法后取模数

编辑:递归乘法会更快

    public static long pow1(int a,long b,long n){
        if (b==1)return a%n;
        if (b%2==1){
            return (pow1(a,(b-1)/2,n)*a)%n;
        }
        else{
            return (pow1(a,b/2,n))%n;
        }
    }

答案 2 :(得分:0)

递归代码中缺少一个因素

def pow1(a,b,n):
    if (b==1):
        return a%n
    if (b%2==1):
        return (pow1(a,(b-1)//2,n)*pow1(a,b//2,n)*a)%n
    else:
        return (pow1(a,b//2,n)*pow1(a,b//2,n))%n