JAVA中的大数组

时间:2018-12-26 13:48:11

标签: java

我正在尝试使用Eratosthenes筛子解决Spoj主发电机,但出现NZEC错误。有谁能够帮助我 。一些用户说使用筛子已经可以帮助我。

import java.util.*;
public class Main
{
    public static void main (String args[])
    {
        Scanner sc =new Scanner(System.in);
        int n =sc.nextInt();
        int g,h;
        int isPrime[]=new int[1000000000];
        for (int j=3;j<1000000000;j++)
        {
            isPrime[0]=0;
            isPrime[1]=0;
            isPrime[2]=1;
            if(j%2==0)
                isPrime[j]=0;
            else
            isPrime[j]=1;
        }
        for(int k=3;k<=Math.sqrt(1000000000);k=k+2)
        {
            if(isPrime[k]==1)
                for (int l=k*k;l<1000000000;l=l+k)
            {
                isPrime[l]=0;
            }
        }
        for (int i=0;i<n;i++)
        {
            g =sc.nextInt();
            h =sc.nextInt();
            for (int m=g; m<=h;m++)
            {
                if(isPrime[m]==1)
                    System.out.println(m);
            }
            System.out.println();
        }
        System.exit(0);
    }
}`

2 个答案:

答案 0 :(得分:0)

简单筛子可能无法在给定的时间内运行。至少它不适合我。更好的方法是分段筛。以下是一些可能对您有帮助的链接:

stackoverflow

primesieve

我使用第二个链接来理解和解决问题。但是第一个链接也有很好的解释。 经历两个步骤,您应该就能解决问题。 祝您编码愉快!

PS::您似乎正在使用Scanner读取输入。会很慢。使用BufferedReader可以加快输入的读取速度。在SPOJ这样的网站中,这一点至关重要。

答案 1 :(得分:0)

唯一的原因是JVM应该有足够的空间来存储new boolean[total + 1]左右的4Gb

public static void main(String... args) {
    boolean[] primes = primes(1_000_000_000);

    try (Scanner scan = new Scanner(System.in)) {
        int n = scan.nextInt();

        for (int i = 0; i < n; i++) {
            int from = scan.nextInt();
            int to = scan.nextInt();

            for (int j = from; j <= to; j++)
                if (primes[j])
                    System.out.println(j);

            System.out.println();
        }
    }
}

private static boolean[] primes(int total) {
    // initially assume all integers are primes
    boolean[] primes = new boolean[total + 1];
    Arrays.fill(primes, true);
    primes[0] = false;
    primes[1] = false;

    // mark non-primes <= total using Sieve of Eratosthenes
    for (int i = 2; i * i <= total; i++) {
        // if i is primes, then mark multiples of i as nonprime
        // suffices to consider mutiples i, i+1, ...,  total/i
        if (!primes[i])
            continue;
        for (int j = i; i * j <= total; j++)
            primes[i * j] = false;
    }

    return primes;
}