我一直在努力解决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();
}
}
如何为此问题编写快速运行的代码。
答案 0 :(得分:0)
我认为你需要采用更多的数学方法解决这个问题。
您想要的号码有哪些属性?
您知道目标号码x将是素数,并且它不是任何数字y&lt; = n的因子。
考虑y = 2 * x。 x是这个因子,所以如果2 * x <= n,我们知道x不是我们的目标数字之一。
尝试找到一种快速计算所有素数p的方法,使得p <= n且2 * p> Ñ