将给定数字的所有因子标记为非素数的算法(尽管它们是素数)
Algorithm to mark all factors of a given number as not prime (they are prime numbers though)
我一整天都在尝试解决 this problem,但我一次又一次地得到 "time limit exceeded"。
我的任务:给定数字 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
我认为你需要用更数学的方法来解决这个问题。
提示 2
您想要的数字有哪些属性?
提示 3
你知道目标数 x 是质数,而且它不是任何数 y<=n 的因数。
考虑 y=2*x。 x 是一个因素,所以如果 2*x<=n,我们知道 x 不是我们的目标数字之一。
提示 4
尝试找到一种快速计算所有素数 p 的方法,使得 p<=n 且 2*p > n。
我一整天都在尝试解决 this problem,但我一次又一次地得到 "time limit exceeded"。
我的任务:给定数字 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
我认为你需要用更数学的方法来解决这个问题。
提示 2
您想要的数字有哪些属性?
提示 3
你知道目标数 x 是质数,而且它不是任何数 y<=n 的因数。
考虑 y=2*x。 x 是一个因素,所以如果 2*x<=n,我们知道 x 不是我们的目标数字之一。
提示 4
尝试找到一种快速计算所有素数 p 的方法,使得 p<=n 且 2*p > n。