Статья Автор: Лебедев Дмитрий

Пишем SOFT своими руками: для решения задании с числами

Для решения ряда заданий, связанных с обработкой чисел, могут пригодиться программы, выполняющие следующие задания:
  • определение нетривиального делителя числа. Если у числа нет нетривиального делителя, то оно простое или единица
  • получения "факторизации" числа (представление \(N = P_1^{a_1}\cdot . . . \cdot P_k^{a_k},\ где\ все\ P_i - \ различные\ простые\ числа, a_i > 0 \).
    Из курса алгебры (Основная теорема арифметики) известно, что такое представление существует и единственно
  • Определение количества делителей числа, их состава и суммы

Программа определения "минимального нетривиального делителя числа".
Входные данные 
  • n - число для обработки
  • d - "точка старта делителя". По умолчанию равен 3
Выходные данные
  • 1 при n=1
  • 2 для всех чётных чисел
  • минимальный нечётный делитель n, не меньший d
Введение дополнительного параметра позволит оптимизировать другие программы


В следующем боксе можно проверить работу программны в разных режимах.
Приведен фрагмент, проверяющий "число на простату" (текст подрограммы скрыт) 


Подсчёт делителей числа
Очень частно можно встретить задания на подсчет делителей числа, поиск числа с максимальным числом делетелей или с заданным числом делителей. Сформулируем самое простое задание такого типа 
Задание 
Для числа N определите число всех его делителей, включая единицу и само число.
"Наивное"  решение могло бы таким 


Возникает вопрос, а что плохого в таком решении?
Рассмотрим следующую ситуацию n = p
Здравый смысл подсказывает, что у такого числа всего m+1 делитель: 1, p, p2, ..., pm
Попробуем это подсчитать с помощью программы  
Попробуй ввести различные значения p и m и позапускать программу 
Так для p = 31 и m = 31 время работы будет в районе 5 сек.,
а для  p = 37 и m = 10 будет превышен лимит времени (10 сек)


Для "оптимизации"  поиска числа делителей надо знать, что если 
\(N = P_1^{a_1}\cdot . . . \cdot P_k^{a_k},\ где\ все\ P_i - \ различные\ простые\ числа, a_i > 0 \)
то число  \(\Huge{\sigma}_{\large0}\large (N) = (a_1+1)\cdot(a_2+1)\cdot . . . \cdot(a_k+1)\) равно количеству всех делителей числа. 
Доказать это не очень сложно, но пока примем это без доказательства.
Есть еще одна "полезная" формула, определяющая сумму всех делителей числа:
\(\Huge{\sigma}_{\large1}\large (N) = \frac{(P_1^{a_1+1}-1)}{p_1-1}\cdot\frac{(P_2^{a_2+1}-1)}{p_2-1}\cdot . . .\cdot\frac{(P_k^{a_k+1}-1)}{p_k-1}\)
Напишем программу, которая, для заданного N, будет вычислять значения \(\Huge{\sigma}_{\large0}\normalsize\ ,\ \Huge{\sigma}_{\large1} \)и список  пар [(P1,a1), ... ,(Pk,ak)]
Программа будет использовать подпрограмму mindel 


Можно запустить эту программу для числа 10! = 3628800 или для
3710 = 4808584372417849
Поясним некоторые детали алгоритма.
Для чётного n первый вызов в строке 6 вернет значение 2 и
следующий вызов будет mindel(x,2) !? 
Это "не будет страшным", поскольку mindel автоматически увеличит 2 на 1 !!!
(Это и было предусмотрено при написании mindel)

Несколько интересных фактов из свойств числа делителей:
  • Количество делителей "квадрата" - нечётное число
  • Если количество делителей числа есть нечётное, то это число - "квадрат"
  • Если количество делителей числа есть простое число, то это число степень простого
  • Количество нечётных делителей у числа  N  и числа 2N одинаково
Доказательства этих свойств оставим для упражнения.
В следующей тетради разберем типовые задания и напишем программу для построения списка всех делителей на основе  результатов факторизации
Пропустить Навигационные Ссылки.
Чтобы оставить комментарий нужна авторизация
Печать