将给定数字的所有因子标记为非素数的算法(尽管它们是素数)

时间:2016-02-26 18:45:43

标签: algorithm math dynamic-programming primes number-theory

我一直在努力解决this problem,但我一次又一次地“超出时间限制”。

我的任务:给定数字N,我必须排除[2;之间的所有素数。 N]是该范围之间其他数字的因子[2; N]。

这是我的代码:

public class Main {

    public static final int SIEVE_LIMIT = 10000001;

    public static final boolean[] COMPOSITES = new boolean[SIEVE_LIMIT];

    private static final ArrayList<Integer> PRIMES = new ArrayList<Integer>();

    public static void main (String[] args) throws NumberFormatException, IOException {

        BufferedReader inStream = null;
        BufferedWriter outStream = null;
        int numCases, curNum, counter;
        StringBuilder resultBuilder = new StringBuilder();
        boolean []temporary = null;

        COMPOSITES[0] = true;
        COMPOSITES[1] = true;

        for(int i = 2; i*i < SIEVE_LIMIT; i++){
            if(!COMPOSITES[i])
                for(int j = i*i; j < SIEVE_LIMIT; j+=i) {
                    COMPOSITES[j] = true;
            }
        }

        for (int i = 2; i < SIEVE_LIMIT; i++) {
          if (!COMPOSITES[i]) 
              PRIMES.add(i);
        }

        inStream = new BufferedReader(new InputStreamReader(System.in));
        outStream = new BufferedWriter(new OutputStreamWriter(System.out));

        numCases = Integer.parseInt(inStream.readLine());

        for(int i = 0; i < numCases; i++){

            curNum = Integer.parseInt(inStream.readLine());
            counter = 0;                        
            temporary = new boolean[SIEVE_LIMIT];

            **// I can't improve this part of the code**
            for(int j = curNum; j > (int) Math.ceil(Math.sqrt(curNum)); j--){

                if(!temporary[j]){
                    for(int aPrime: PRIMES){

                    if(aPrime > (int) Math.ceil(Math.sqrt(j))) break;

                    if(temporary[aPrime]) break;

                    if (j % aPrime == 0) {
                        temporary[aPrime] = true;

                    }                   
                }
            }
        }

        for(int j = 2; j <= curNum; j++) {
            if(!temporary[j] && !COMPOSITES[j])
            counter++;
        }
        //......

        resultBuilder.append(Integer.toString(counter) + '\n');         
    }

      inStream.close();
      outStream.write(resultBuilder.toString().trim() + '\n');
      outStream.close();   
    }
}

如何为此问题编写快速运行的代码。

1 个答案:

答案 0 :(得分:0)

提示1

我认为你需要采用更多的数学方法解决这个问题。

提示2

您想要的号码有哪些属性?

提示3

您知道目标号码x将是素数,并且它不是任何数字y&lt; = n的因子。

考虑y = 2 * x。 x是这个因子,所以如果2 * x <= n,我们知道x不是我们的目标数字之一。

提示4

尝试找到一种快速计算所有素数p的方法,使得p <= n且2 * p> Ñ