Проверить программы онлайн · файлы остаются в браузере
10 класс, углублённый уровень. Занятие шестое: цикл по переменной и чем он отличается от цикла с условием, делители и простые числа, перебор отрезка — форма задания 25 ЕГЭ.
Проверка.bat из общей папки: она запускает программу на семи
наборах данных. Интернет не нужен.
Шесть типов задач, по одной на каждый. Считать в уме или на бумаге: запустив программу, вы узнаете ответ, но не научитесь. Ответ — ровно то, что появится на экране; если программа печатает несколько строк, перечисли их через пробел. Последний тип — задание 25 ЕГЭ в уме: там кода нет вовсе, числа перебираем в голове, отрезок для этого подобран короткий.
range(a, b) даёт числа от a до b − 1. Чтобы
дойти до самого n, пишут range(1, n + 1) — это самая
частая правка в задачах про делители. После цикла переменная хранит
последнее пройденное значение.
Любой for переписывается через while, и наоборот. Разница
в удобстве: for берут, когда число шагов известно заранее («перебрать
делители от 1 до n»), while — когда его определяет сама задача («пока
делится», «пока не нашли»). Два отличия, из которых растут ошибки:
while в переменной остаётся первое неподошедшее
значение, после for — последнее пройденное;for бесполезно: на следующем проходе
range выдаст очередное значение. В while такая строка
сдвинула бы все шаги.Тот же цикл со s = s + d даёт сумму делителей, с
print(d) — их список, с m = d — наибольший (максимум
накоплением: последний найденный и есть наибольший). Делители ходят
парами: если d делит n, то и n // d делит.
Один из пары не больше корня из n — отсюда все быстрые проверки.
Простое — то, у которого ровно два делителя: 1 и само число. Поэтому 1 — не простое (у него один делитель), а 2 — простое, и единственное чётное.
Почему до корня: если у n есть делитель больше корня, парный ему
меньше корня — и нашёлся бы раньше. Для миллиона это тысяча проверок вместо
миллиона.
Здесь шаг делает не счётчик, а само число: 60 → 30 → 15 → 5 → 1. Пока
n делится на d, снимаем d снова и снова: 64 даст
шесть двоек. Составным d не окажется никогда: все его простые множители
к тому моменту уже сняты.
В задании 25 дан отрезок или начало перебора и свойство: «числа, у которых ровно шесть делителей», «произведение двух простых», «делители с такой-то цифрой». Надо перебрать числа по порядку, для каждого проверить свойство и напечатать подходящие вместе с чем-то ещё — обычно с делителем. Это два вложенных цикла: внешний по отрезку, внутренний по делителям. Ниже — схема для первого из этих свойств: ровно шесть делителей.
range(a, b) без + 1 — правый
конец отрезка не проверяется, и ошибка вылезает только тогда, когда он сам
подходит под условие. И if вместо while при разложении:
множитель снимается один раз, а он мог войти дважды.
zadanie1.py, zadanie2.py, zadanie3.py.input(). Пиши input(),
а не input("Введите число: ") — вывод читает машина.Программа читает натуральное число (от 1 до 100000) и печатает
три строки: все его делители по возрастанию через пробел, их количество и
простое ли это число. Напомним: у простого ровно два делителя.
28
Делители: 1 2 4 7 14 28 Количество: 6 Простое: нет
Проверяется: по
с правой границей,
счётчик и накопитель-строка, ветвление после цикла.
Перебор , внутри проверка
. Делители копи в строке, как траекторию в прошлый
раз: перед циклом
, на каждом найденном
, после цикла
. Количество — обычный счётчик.
Ловушка, ради которой это задание. Простое ли число, честнее всего
решать по количеству делителей: ровно два — простое. Тогда единица сама собой
окажется не простой (у неё один делитель), а 2 — простой. Оболочка подаст
1, 2, 4 и большие простые. И проверь, что доходит до самого
: без
само число в делители не попадёт.
Программа читает натуральное число (от 2 до 1000000) и
печатает его разложение на простые множители: сами множители по неубыванию через
пробел, их количество и наибольший из них. Для простого числа множитель один —
оно само.
360
Множители: 2 2 2 3 3 5 Количество: 6 Наибольший: 5
Проверяется: цикл с условием, в котором шаг делает само число; «пока делится» вместо «если делится»; хвост после цикла.
Самый простой способ — из разбора выше: ,
, делится — запомнили
и поделили,
не делится —
. Для миллиона он успевает. Наибольший
множитель — последний снятый, его не надо искать отдельно: просто перезаписывай
переменную при каждом снятии.
Ловушки, ради которых это задание. Оболочка подаст 64 — там
двойка входит шесть раз, и вместо
снимет её
один раз. И подаст 194 = 2 · 97: если ты перебираешь
только до
корня из
, после цикла останется 97 — это тоже множитель, и его
надо напечатать (
).
Задача в форме задания 25 ЕГЭ. Программа читает три числа, каждое со своей
строки: границы отрезка и
(1 ≤ a ≤ b ≤ 5000, в отрезке не
больше 200 чисел) и
(от 2 до 12). Для каждого числа отрезка, у
которого ровно
делителей, печатает строку из двух чисел: само число и
его наибольший делитель, не равный ему. Последней строкой — «Найдено:» и сколько
таких чисел; эта строка печатается всегда, даже если не найдено ничего.
95 100 6
98 49 99 33 Найдено: 2
Проверяется: вложенные циклы, счётчик внутри и снаружи,
, максимум накоплением.
Внешний цикл перебирает отрезок,
внутренний
считает делители этого
. Счётчик делителей обнуляй внутри внешнего цикла, перед
внутренним — иначе он накопит делители всех чисел сразу. Наибольший делитель,
не равный числу, — максимум накоплением среди
: каждый
найденный перезаписывает
, последний и есть наибольший.
Ловушки, ради которых это задание. Оболочка подаст отрезок
с
: оба конца подходят, и
без
потеряет 99. Подаст
— отрезок из одного числа. И подаст отрезок, где не
подходит ничего: тогда единственная строка вывода —
.
zadanie1.py … zadanie3.py лежат в твоей
папке, отладочные print из них убраны.Проверка.bat.Оболочка показывает, на каких данных программа ошиблась и что должна была вывести. Это подсказка: исправляй и проверяй снова, попыток сколько угодно.
range(a, b) — числа от a до b − 1: правая граница не входит, до самого n доходит range(1, n + 1). range(n) начинается с нуля и даёт n чисел. Третье число — шаг: range(1, 10, 3) даёт 1, 4, 7; range(10, 0, −2) идёт вниз: 10, 8, 6, 4, 2. range(5, 1) без шага пуст. После for переменная хранит последнее пройденное значение; менять её внутри тела бесполезно.
Любой цикл переписывается другим. for — когда число шагов известно заранее (перебрать d от 1 до n), while — когда его определяет задача (пока делится, пока не нашли). После while в переменной первое неподошедшее значение, после for — последнее пройденное. В while шаг делает сам программист — иначе вечный цикл.
n % 10 — последняя цифра, n // 10 отрезает её; while n > 0 перебирает все. Накопитель стартует с нуля для суммы, с единицы для произведения, с 9 для минимума цифры; флаг «есть ли цифра» стартует с «нет».
for d in range(1, n + 1): if n % d == 0 — перебор всех делителей; счётчик даёт их количество, накопитель — сумму, m = d — наибольший. Делители ходят парами d и n // d, один из пары не больше корня из n; у точного квадрата одна пара схлопывается, поэтому делителей нечётное число: у 49 их три.
Ровно два делителя: 1 и само число. 1 — не простое, 2 — единственное чётное простое. Проверка: флаг prime = n > 1 ставится один раз до цикла, в цикле только сбивается; перебирать d достаточно, пока d · d ≤ n. Наименьший делитель больше единицы всегда простой.
d = 2; while n > 1: делится — снять d и поделить (d не двигать: он мог войти ещё раз), не делится — d = d + 1. 60 = 2 · 2 · 3 · 5. Если перебирать d только до корня, остаток n > 1 после цикла — тоже множитель (194 = 2 · 97). Ровно три делителя бывает у квадрата простого, четыре — у p · q или p³.
Перебрать числа отрезка по порядку, для каждого проверить свойство (число делителей, вид разложения), напечатать подходящие и что просят рядом — обычно делитель. Два вложенных цикла: внешний по отрезку, range(a, b + 1); внутренний по делителям, счётчик обнуляется перед ним. Строку с итогом печатать всегда, даже когда найдено ноль.
Материалы подготовлены с использованием технологий искусственного интеллекта.