Перебор

Цикл по переменной, делители и простые числа.
10 класс, углублённый уровень — занятие шестое.

Три урока плана за одну пару: for по range мы уже писали, цифры числа доставали в прошлый раз. Новое сегодня одно, зато большое: перебор как метод решения — и задание 25 ЕГЭ как его экзаменационная форма.

range: три числа, а не одно

for i in range(5):           # 0 1 2 3 4
for i in range(2, 6):        # 2 3 4 5
for i in range(1, 10, 3):    # 1 4 7
for i in range(10, 0, -2):   # 10 8 6 4 2

Начало, конец, шаг. Без начала — с нуля. Без шага — по единице. Правая граница не входит никогда.

Ловушка 1: до n или до n − 1?

Так — неверно

n = 6
for d in range(1, n):
    if n % d == 0:
        print(d)

Напечатает 1 2 3. Сама шестёрка потеряна.

Так — верно

n = 6
for d in range(1, n + 1):
    if n % d == 0:
        print(d)

Напечатает 1 2 3 6.

for или while — одно и то же

for — шагов известно

for d in range(1, n + 1):
    if n % d == 0:
        print(d)

«Перебрать всё от 1 до n».

while — то же самое руками

d = 1
while d <= n:
    if n % d == 0:
        print(d)
    d = d + 1

Шаг делаем сами.

Ловушка 2: что осталось в переменной

После while

i = 1
while i < 10:
    i = i + 1
print(i)      10

Первое неподошедшее значение.

После for

for i in range(1, 10):
    s = i
print(i)      9

Последнее пройденное.

Цифры числа: четыре накопителя

Что ищемСтартВ теле
сумма цифрs = 0s = s + n % 10
произведениеp = 1p = p * (n % 10)
минимальная цифраm = 9if n % 10 < m: m = n % 10
есть ли цифра 7f = "нет"if n % 10 == 7: f = "да"
while n > 0:
    ...                 # одна из строк таблицы
    n = n // 10         # отрезать последнюю цифру

Делители и простые

Перебор как метод.

Делители: перебрать всё от 1 до n

k = 0
for d in range(1, n + 1):
    if n % d == 0:
        k = k + 1
print(k)             # сколько делителей

Тот же цикл со s = s + d — сумма, с print(d) — список, с m = d — наибольший.

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

Ровно два делителя: 1 и само число.

  • 1 — не простое: у неё один делитель.
  • 2 — простое, и единственное чётное.
prime = n > 1            # флаг ставится ОДИН раз, до цикла
d = 2
while d * d <= n:
    if n % d == 0:
        prime = False    # в цикле флаг только сбивают
    d = d + 1

Ловушка 3: флаг, который сбрасывается

Так — неверно

for d in range(2, n):
    if n % d == 0:
        prime = False
    else:
        prime = True

Последний проход — d = n − 1, на него n не делится, и флаг снова True. Любое число «простое».

Так — верно

prime = True
for d in range(2, n):
    if n % d == 0:
        prime = False

Флаг ставят до цикла, в цикле только сбивают.

Разложение на множители

d = 2
while n > 1:
    if n % d == 0:        # делится — снять множитель
        print(d)
        n = n // d        # d НЕ двигаем: мог войти ещё раз
    else:
        d = d + 1
# n = 60:  60 --2--> 30 --2--> 15 --3--> 5 --5--> 1

Задание 25 ЕГЭ: перебор с отбором

В демоварианте 2027: перебирать числа, большие заданного, в порядке возрастания и искать те, что являются произведением ровно двух простых множителей — с дополнительным условием на запись множителей. В ответ — первые пять найденных чисел и для каждого наименьший множитель.

Форма всегда одна: перебрать по порядку → проверить свойство → напечатать число и что-то рядом. Свойство почти всегда про делители.

Считать делители, не перебирая

Сколько делителейКакие числаПример
ровно 2простые2, 3, 5, 7, 11
ровно 3квадрат простого4, 9, 25, 49
ровно 4p · q или p³6, 10, 14, 15, 8, 27
нечётноеточные квадраты1, 4, 9, 16, 25

Для сильных: степень за считанные умножения

Сколько умножений нужно, чтобы посчитать x16? Пятнадцать подряд — или четыре, если возводить в квадрат: x² → x⁴ → x⁸ → x¹⁶.

r = 1
while n > 0:
    if n % 2 == 1:        # нечётная степень — снять одну x
        r = r * x
    x = x * x             # дальше работаем с квадратом
    n = n // 2

Что делаем сегодня

№ПрограммаРади чего
1Делители: список, количество, простое ли число for по range до n + 1, накопитель-строка
2Множители: разложение на простые, количество, наибольший while, где шаг делает само число; «пока делится»
3Ровно k делителей: перебрать отрезок, напечатать число и его наибольший делитель вложенные циклы — форма задания 25 ЕГЭ

Как работаем

  1. Открываем практикум из общей папки — сначала тренажёр: шесть задач на чтение кода, оценки за него нет.
  2. Пишем три программы в IDLE, сохраняем в свою папку как zadanie1.py, zadanie2.py, zadanie3.py.
  3. Запускаем Проверка.bat → «Найти мои файлы» → «Проверить всё».
  4. Показываем отметку с экрана.
Приглашений в input() быть не должно: input(), а не input("Введите число: "). Вывод читает машина. Списков не нужно: числа копятся в строке, как траектория в прошлый раз.

Отметка: три задания — «5», два — «4», одно — «3». Попыток сколько угодно, оболочка каждый раз показывает, на каких данных программа ошиблась.

За работу

Сначала тренажёр, потом три программы.

Домашнее задание — на странице «Домашнее задание»: шесть типов задач на чтение кода и перебор в уме, Python дома не нужен. В начале следующей пары — проверочная по этим же типам.

Материалы подготовлены с использованием технологий искусственного интеллекта. Пробел раскрыть и дальше · ← → слайды