Школа программиста
Резервная копия - VPS Hoster 

Забыли пароль?
[задачи] [курсы] [олимпиады] [регистрация]
Логин:   Пароль:    
Скрыть меню
О школе
Правила
Олимпиады
Фотоальбом
Гостевая
Форум
Архив олимпиад
Архив задач
Состояние системы
Рейтинг
Курсы
Новичкам
Работа в системе
Алгоритмы
Курсы ККДП
Дистрибутивы
Ссылки

HotLog


 

Простые числа

(Время: 0,5 сек. Память: 32 Мб Сложность: 28%)

Масса олимпиадных задач связаны с простыми числами, в частности с их поиском и определением простоты. Поэтому, прежде чем начинать разбор данной задачи, поговорим сначала о том, как определить простоту конкретного числа. Известно, что если число n составное, то один из его делителей не превосходит значения sqrt(n), поэтому при проверке на делимость числа n достаточно перебрать всевозможные делители от 2 до sqrt(n). Это можно оформить в виде следующей функции:

  bool IsPrime(int n){
    int i;
    for i=2..sqrt(n)
     if(n mod i = 0) return false;
    return true;
  }

Описанную выше функцию можно ускорить вдвое, если проверять делимость только на нечетные числа, а делимость на 2 рассмотреть отдельно. Так же когда уже известны все простые числа, не превосходящие sqrt(n), то еще более разумно проверять делимость только на них, тогда скорость возрастет в ln(sqrt(n)) раз. Следующий фрагмент программы демонстрирует заполнение массива p[i] простыми числами от 2 до n:

  p[1]=2; np=1               //в массив p вносим первое простое число 2 (всего np чисел)
  for x=3..n{                //цикл по нечетным значениям x, которые проверяем на простоту
    j=1; Ok=true;
    while(p[j]*p[j]<=x){     //проверяем число x на делимость на возможные раннее найденые простые числа
      if(x mod p[j] = 0){
        Ok=false; break
      }
      j=j+1
    }
    if(Ok){                  //если делитель не найден, то добавляем данное число в список простых
      np=np+1
      p[np]=x
    }
  } 

Для того, чтобы довести вышеописанный алгоритм до алгоритма решения исходной задачи достаточно в процессе поиска проверять добавление нового простого числа на попадение в заданный отрезок и выводить его в случае принадлежности. И не забудьте про двойку!


[Обсуждение] [Все попытки] [Задача]


Красноярский краевой Дворец пионеров, (c)2006 - 2019, ICQ: 151483, E-mail: admin@acmp.ru