Я столкнулся со следующим вопросом на веб-сайте программирования: Питер хочет сгенерировать несколько простых чисел для своей криптосистемы. Помоги ему! Ваша задача - сгенерировать все простые числа между двумя заданными числами!
Вход
Ввод начинается с количества t тестов в единственной строке (t ‹= 10). В каждой из следующих t строк есть два числа m и n (1 ‹= m‹ = n ‹= 1000000000, n-m‹ = 100000), разделенных пробелом.
Я пришел к следующему решению:
import java.util.*;
public class PRIME1 {
static int numCases;
static int left, right;
static boolean[] initSieve = new boolean[32000];
static boolean[] answer;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
numCases = sc.nextInt();
initSieve[0] = true;
initSieve[1] = true;
Sieve();
for (int j = 0; j < numCases; j++) {
String line = sc.next();
String line2 = sc.next();
left = Integer.parseInt(line);
right = Integer.parseInt(line2);
answer = new boolean[right - left + 1];
getAnswer();
for (int i = 0; i < answer.length; i++) {
if (!answer[i]) {
int ans = i + left;
System.out.println(ans);
}
}
System.out.println();
}
}
public static void Sieve() {
for (int i = 2; i < 32000; i++) {
if (!initSieve[i]) {
for (int j = 2 * i; j < 32000; j += i) {
initSieve[j] = true;
}
}
if (i * i > 32000)
break;
}
}
public static void getAnswer() {
for (int i = 2; i < 32000 && i <= right; i++) {
if (!initSieve[i]) {
int num = i;
if (num * 2 >= left) {
num *= 2;
} else {
num = (num * (left / num));
if (num < left)
num += i;
}
for (int j = num; j >= left && j <= right; j += i) {
answer[j - left] = true;
}
}
}
}
}
Я отредактировал свое решение после прочтения некоторых предложений. Я все еще получаю сообщение об ошибке «Превышен лимит времени». Есть еще предложения о том, как еще больше оптимизировать это? Я вычисляю все простые числа до 32000, а затем использую их, чтобы найти простые числа от n до m.
Спасибо, Рохит
√(isNotPrime.length)
. Несвязанный: у сканера есть метод nextInt. - person user unknown   schedule 22.05.2012i+=2
вfor (int i = 0; i < answer.length; i+=2)
. Убедитесь, чтоi
соответствует нечетному числу не ниже вашегоleft
. Никакое четное число больше 2 никогда не будет простым. :) Это была бы разреженная схема адресации, еще быстрее будет работать со сжатым массивом, где запись с индексомi
представляет собой числоn=left_odd + 2i
. ВнутриSieve()
также работайтеj+=2*i
(хотя это сито очень маленькое), но, что более важно, внутриgetAnswer()
. Посмотрите на ответ Дэниела. - person Will Ness   schedule 23.05.2012