Привет, друг! Ты на курсе Профиматики и готовишься к ЕГЭ по информатике. Python — это твой главный инструмент для решения многих задач на экзамене. С его помощью ты сможешь быстро перебирать варианты, обрабатывать строки и числа и не тупить на сложных алгоритмах. Это руководство мы написали специально для тебя: в нём нет ничего лишнего, только то, что реально пригодится на ЕГЭ. Мы объясняем на пальцах, даём шпаргалки и сразу показываем, где какая тема выстрелит на экзамене. Погнали!
Суть такая: на ЕГЭ Python нужен в задачах 2, 6, 8, 9, 14, 15, 16, 17, 19-21, 23, 24, 25, 26 и 27. Это больше половины всех заданий. Мы не будем учить тебя делать сайты или игры — только то, что приносит баллы на экзамене. Поехали по главам.
Прежде чем писать код, нужно установить Python на компьютер и настроить среду, в которой ты будешь работать. Это просто, мы делаем это один раз в самом начале, и дальше ты просто открываешь файл и пишешь код. Не парься, если сразу не понятно — просто делай по шагам.
Заходим на официальный сайт: python.org. Нажимаем большую жёлтую кнопку Download Python — сайт сам определит твою операционную систему и предложит нужную версию.
Скачай установщик (файл с расширением .exe).
Запусти его.
В самом первом окне обязательно поставь галочку внизу: «Add Python to PATH». Если пропустишь — Python не будет виден в командной строке, и код не запустится.
Нажми Install Now и дождись окончания установки.
Проверь: открой командную строку (Win + R, введи cmd) и напиши:
python --version
Python можно писать в обычном Блокноте, но это неудобно: нет подсветки синтаксиса, нет автоподстановки, и ошибки сложно найти. IDE (среда разработки) — это программа, которая помогает писать код: подсвечивает команды, показывает ошибки на ходу, даёт подсказки. Твой код будет читаемым и понятным, а не «кашей».
На ЕГЭ по информатике у тебя будет выбор: Wing IDE 101 или PyCharm. Обе среды уже установлены на компьютерах в аудиториях. Ты можешь работать в той, которая тебе удобнее. Главное — заранее попробовать обе и выбрать свою.
Wing IDE 101 — бесплатная версия для обучения. Скачай её на официальном сайте wingware.com (раздел Wing IDE 101). Устанавливается как обычная программа — просто запускаешь установщик и жмёшь «Далее».
Верхняя панель — меню (Файл, Правка, Запуск и т.д.).
Левая часть — список твоих файлов (браузер проекта).
Центральная часть — редактор, где ты пишешь код.
Нижняя часть — окно вывода, куда печатается результат твоей программы (Debug I/O). Это самое главное окно — там ты увидишь, что вывела твоя программа.
Чтобы создать новый файл: File → New (или Ctrl+N).
Чтобы сохранить файл: File → Save (Ctrl+S). Название должно заканчиваться на .py, например task25.py.
Чтобы запустить код: нажми зелёную стрелку на панели инструментов (или F5).
Результат появится в нижнем окне Debug I/O.
Очень простая, ничего лишнего.
Легко разобраться с нуля.
На экзамене работает быстро и стабильно.
Подсвечивает синтаксические ошибки красным — видно сразу.
PyCharm от JetBrains — скачай бесплатную версию Community с сайта jetbrains.com/pycharm/download. Установка простая — запускаешь установщик и следуешь инструкциям.
Слева — дерево проекта (твои файлы и папки).
По центру — редактор кода (там пишешь).
Снизу — окно терминала и вывода результатов (Run).
Создай новый проект или открой существующий.
Чтобы создать новый файл: правая кнопка по папке → New → Python File.
Чтобы запустить код: нажми зелёный треугольник справа от номера строки (или Ctrl+Shift+F10).
Результат появится в нижнем окне Run.
Мощные подсказки и автодополнение — код пишется быстрее.
Умный поиск ошибок — часто говорит, что именно не так.
Удобная работа с большими проектами (если у тебя много файлов с задачами).
Тяжелее, чем Wing IDE (может чуть дольше запускаться).
Больше настроек — можно запутаться, если не привык.
Мой совет: попробуй обе дома. Если тебе нужна простота и надёжность — бери Wing IDE 101. Если хочешь мощные подсказки и комфортную работу с кодом — бери PyCharm. На экзамене ты сможешь открыть любую из них. Главное — тренируйся дома в той же среде, чтобы на экзамене не тратить время на привыкание.
Теперь создадим первый файл и напишем код. Выбери свою среду и делай по шагам.
Открой Wing IDE 101.
Нажми File → New (Ctrl+N) — откроется пустой редактор.
Напиши код:
print("Привет, ЕГЭ!")
Вот и всё! Ты только что написал свою первую программу на Python в среде, которая будет доступна на ЕГЭ.
Запомни:
print()— это команда вывода на экран. Всё, что внутри кавычек, печатается как текст.
С этого момента ты уже не просто читаешь про Python — ты пишешь на нём.
Каждая новая задача — это новый файл. Просто создаёшь task6.py, task8.py и так далее. Код пишешь, сохраняешь, запускаешь. Если ошибся — поправляешь и запускаешь снова.
Действие | Wing IDE 101 | PyCharm |
|---|---|---|
Создать файл |
| ПКМ по папке → |
Сохранить файл |
|
|
Запустить код | Зелёная стрелка или | Зелёный треугольник или |
Где смотреть результат | Окно Debug I/O внизу | Окно Run внизу |
Python установлен (проверь через python --version в командной строке).
Выбрана и установлена среда (Wing IDE 101 или PyCharm).
Первый файл first.py создан, запущен и написал «Привет, ЕГЭ!».
Теперь ты полностью готов к решению задач. Погнали! 🚀
Это самая база, с которой начинается любой код. Без неё ты не выведешь ответ и не посчитаешь даже простую сумму. Нужна вообще везде — от задачи 2 до задачи 27.
Представь, что твоя программа — это калькулятор. Ты что-то в него вводишь (ввод), он считает (арифметика) и показывает результат (вывод). Всё. Три кита, на которых стоит любая программа.
Вывести что-то на экран — команда print():
print("Привет, ЕГЭ!") # выведет текст
print(2 + 2) # выведет число 4
Считать данные с клавиатуры — команда input(). Но на ЕГЭ чаще ты сам задаёшь числа в коде, так что input() нужен реже.
Основная арифметика, которую зубрить обязательно:
a = 17
b = 5
print(a + b) # 22 — сложение
print(a - b) # 12 — вычитание
print(a * b) # 85 — умножение
print(a / b) # 3.4 — деление (всегда даёт дробь!)
print(a // b) # 3 — целочисленное деление (отбрасывает дробную часть)
print(a % b) # 2 — остаток от деления
print(a ** b) # 1419857 — возведение в степень
В задаче 7 часто надо посчитать объём памяти. Например, картинка 1024×768, 16 бит на пиксель, сколько Кбайт?
from math import ceil
pixels = 1024 * 768 # всего пикселей
bits = pixels * 16 # всего бит
kbytes = bits / 8 / 1024 # переводим в Кбайты
print(ceil(kbytes)) # округляем вверх
print() — вывести на экран.
+ - * / — обычная арифметика.
// — целочисленное деление (без дробной части).
% — остаток от деления (мегаважно для задач на делимость!).
** — степень.
Деление / всегда даёт дробь, даже 10 / 2 это 5.0, а не 5.
Путают / и //. Запомни раз и навсегда: одна черта — дробь, две черты — целое.
Забывают, что % — это остаток. 10 % 3 это 1, а не 3.33.
Степень — это **, а не ^. Значок ^ в Python означает совсем другое (XOR), и ты получишь неправильный ответ.
Без ветвления программа не сможет принимать решения — а почти в каждой задаче надо что-то проверить: «если число чётное, то...», «если делится, то...».
Конструкция if — это развилка на дороге. Если условие верное — идём налево, если нет — направо. Прямо как в жизни: «Если завтра дождь — беру зонт, иначе — нет».
x = 10
if x > 5: # если условие верное...
print("больше 5") # ...выполняем это (с отступом!)
else: # иначе...
print("не больше 5")
Отступ (4 пробела) — это синтаксис Python. Он показывает, что код относится к if. Без отступа — ошибка.
А что, если вариантов не два, а три и больше? Тут нам и нужен elif (это сокращение от «else if» — «иначе если»). Работает так: Python проверяет условия сверху вниз по очереди. Как только нашёл первое верное — выполняет его блок и дальше уже не проверяет, выходит из всей конструкции.
x = 0
if x > 0:
print("положительное")
elif x < 0: # проверяется, ТОЛЬКО если первое условие ложно
print("отрицательное")
else: # если вообще ни одно не подошло
print("ноль")
Прокрути в голове: при x = 0 первое условие (x > 0) ложно, второе (x < 0) тоже ложно, поэтому срабатывает else. Выведется «ноль».
Важно понять разницу. Если написать несколько отдельных if — Python проверит каждый из них, даже когда один уже сработал:
ball = 75
# Через elif — проверка останавливается на первом подходящем:
if ball >= 80:
print("отлично")
elif ball >= 60: # сюда зайдём, выведем "хорошо" и ВЫЙДЕМ
print("хорошо")
elif ball >= 40:
print("удовлетворительно")
else:
print("пересдача")
Главное правило: elif — это «цепочка», где срабатывает только одна ветка. Используй его, когда варианты взаимоисключающие (число либо положительное, либо отрицательное, либо ноль — третьего не дано).
Условия можно соединять: and (И), or (ИЛИ), not (НЕ).
if x > 0 and x < 100: # x больше 0 И меньше 100
print("от 1 до 99")
В задаче 14 надо найти числа, у которых остаток от деления особый. Без if никак:
for n in range(1, 100):
if n % 7 == 0: # если n делится на 7 без остатка
print(n)
if условие: — если верно, выполняем блок с отступом.
elif — дополнительная проверка, срабатывает только если предыдущие ложны.
В цепочке if/elif/elif/else выполняется ровно одна ветка.
else — что делать, если все условия ложны.
and — И, or — ИЛИ, not — НЕ.
Проверка на равенство — это == (два знака!), а не =.
Отступ обязателен — это часть синтаксиса.
Путают = и ==. Один знак — это присваивание (x = 5), два — это сравнение (x == 5). Вот тут надо быть очень аккуратным, иначе получишь ошибку.
Путают elif и несколько if. Если важно, чтобы сработал только один вариант, — бери elif. Иначе посчитаешь одно и то же дважды.
Забывают двоеточие в конце строки с if.
Сбивают отступы. Твой код должен быть читаемым и понятным, а не «кашей».
Цикл for — это рабочая лошадка для всех задач. Когда нужно перебрать кучу вариантов или пройтись по всем числам в диапазоне — это твой инструмент №1.
for — это когда ты точно знаешь, сколько раз надо что-то повторить. Например, «проверь все числа от 1 до 1000». Ты как будто говоришь программе: «возьми по очереди каждое число и сделай с ним вот это».
for i in range(5): # i пробежит значения 0, 1, 2, 3, 4
print(i)
Функция range() — главный напарник for. Запоминаем формы:
range(5) # 0, 1, 2, 3, 4 (от 0 до 5, не включая 5)
range(2, 7) # 2, 3, 4, 5, 6 (от 2 до 7, не включая 7)
range(1, 10, 2) # 1, 3, 5, 7, 9 (от 1 до 10 с шагом 2)
range(10, 1, -2) # 10, 8, 6, 4, 2 (НАЗАД с шагом -2!)
Обрати внимание на последнюю форму. Если шаг отрицательный, цикл идёт в обратную сторону — от большего к меньшему. Это выручает в задаче 16, где иногда нужно заполнять значения функции «с конца». Прокрути в голове: range(10, 1, -2) стартует с 10, каждый раз вычитает 2 и останавливается, не дойдя до 1, — получаем 10, 8, 6, 4, 2.
for умеет не только считать числа через range(). Он спокойно ходит прямо по элементам любого списка или строки. Это его суперсила.
spisok = [10, 25, 7, 42]
for x in spisok: # x по очереди станет 10, потом 25, потом 7, потом 42
print(x) # выводим каждый элемент
Тут переменная x — это не индекс, а само значение из списка. На первом круге x = 10, на втором x = 25 и так далее, пока список не кончится. Никаких range() и len() — Python сам берёт элементы по порядку.
То же самое работает и со строкой — она перебирается по символам:
for bukva in "ЕГЭ": # bukva станет 'Е', потом 'Г', потом 'Э'
print(bukva)
Когда что выбирать? Если тебе важно только значение — пиши for x in spisok. Если нужен ещё и номер элемента (например, чтобы заглянуть к соседу spisok[i+1]) — тогда идём по индексам через for i in range(len(spisok)). Об этом подробнее в главе про массивы.
Классика задачи 25 на маски — перебрать числа в диапазоне и проверить условие:
for n in range(174457, 174505): # перебираем все числа диапазона
if n % 2025 == 0: # если делится на 2025
print(n, n // 2025) # выводим число и частное
for i in range(n): — повторить n раз, i идёт от 0 до n-1.
range(a, b) — от a до b-1 (правая граница не входит!).
range(a, b, step) — с шагом step.
range(b, a, -1) — идём назад (отрицательный шаг).
for x in spisok: — пройтись по значениям списка/строки.
Тело цикла пишем с отступом.
Правая граница не включается! range(1, 10) это 1...9, а не 1...10. Этот приём выручит тебя в задаче №25, где границы критичны.
В обратном range(10, 1, -2) стоп тоже «не доходя» до правой границы. range(5, 0, -1) это 5,4,3,2,1 (ноль не входит).
Путают: при for x in spisok переменная — это значение, а не индекс. Не пиши spisok[x], ты получишь ошибку или мусор.
Пытаются менять список, пока по нему идёт цикл — так лучше не делать.
while нужен в задачах 5, 14, 24. Особенно в задачах 5 и 14, когда мы переводим число в другую систему счисления и не знаем заранее, сколько будет цифр.
while — это «повторяй, пока условие верно». В отличие от for, ты не знаешь точное число повторений. Как будто говоришь: «копай яму, пока не найдёшь воду».
n = 10
while n > 0: # пока n больше нуля
print(n)
n = n - 1 # обязательно меняем n, иначе зациклимся!
Перевод числа в другую систему счисления (задача 14) — почти всегда через while:
n = 100
s = ''
while n > 0: # пока число не обнулилось
s = str(n % 8) + s # берём остаток (это цифра)
n = n // 8 # уменьшаем число
print(s) # 144 — это 100 в восьмеричной
while условие: — повторяем, пока условие истинно.
Внутри цикла обязательно меняем переменную из условия.
while хорош, когда не знаешь число повторений заранее.
Для перевода в системы счисления while + % + // — золотая связка.
Бесконечный цикл! Если забыл менять переменную в условии — программа зависнет навсегда. Вот тут надо быть очень аккуратным, иначе получишь ошибку (точнее, вечную загрузку).
Путают порядок: сначала берём остаток, потом делим. Не наоборот.
Не парься, если сразу не понятно, просто прокрути пример с переводом в голове на маленьком числе.
Строки — это база для задач 5, 8, 14, 24. В задаче 24 ты вообще работаешь с гигантской строкой из файла, и без срезов там никак.
Строка — это последовательность символов, как вагоны в поезде. У каждого символа есть номер (индекс), и ты можешь вытащить любой символ или кусок строки (срез). Важно: нумерация начинается с нуля!
s = "ЕГЭ2026"
print(s[0]) # Е — первый символ (индекс 0)
print(s[1]) # Г — второй символ
print(s[-1]) # 6 — последний символ (отрицательный индекс!)
Срез — кусочек строки s[начало:конец]:
s = "Профиматика"
print(s[0:4]) # Проф — символы с 0 по 3 (4 не входит)
print(s[:4]) # Проф — то же самое, начало можно не писать
print(s[4:]) # иматика — с 4 до конца
print(s[::-1]) # акитамиорП — строка задом наперёд!
В задаче 8 проверяем, начинается ли слово с нужной буквы:
slovo = "АРБУЗ"
if slovo[0] == 'А': # если первый символ — А
print("начинается с А")
if slovo[-1] in 'АО': # если последний символ — А или О
print("заканчивается на гласную")
Нумерация символов начинается с 0.
s[i] — символ с индексом i.
s[-1] — последний символ.
s[a:b] — срез с a по b-1 (правая граница не входит).
s[::-1] — развернуть строку.
len(s) — длина строки.
Нумерация с нуля! Первый символ — это s[0], а не s[1]. Намертво это запомни, чтобы не тупить на экзамене.
В срезе правая граница не входит — как и в range.
Строку нельзя менять по индексу: s[0] = 'X' выдаст ошибку. Строки в Python неизменяемы.
Методы строк — это готовые «фишки», которые экономят кучу кода. Зачем писать цикл, если есть готовая команда?
Метод — это действие, которое строка умеет делать сама. Пишется через точку: строка.метод(). Например, посчитать, сколько раз встречается буква, — это метод .count().
s = "abracadabra"
print(len(s)) # 11 — длина строки (сколько символов)
print(s.count('a')) # 5 — сколько раз встречается 'a'
print(s.find('cad')) # 4 — с какого индекса начинается 'cad'
print(s.upper()) # ABRACADABRA — всё в верхний регистр
print(s.lower()) # abracadabra — всё в нижний регистр
print(s.replace('a','X')) # XbrXcXdXbrX — заменить a на X
Ещё пачка полезных методов, которые реально встречаются на ЕГЭ:
s = " Привет ЕГЭ 2026 "
print(s.strip()) # "Привет ЕГЭ 2026" — убрать пробелы по краям
print(s.split()) # ['Привет', 'ЕГЭ', '2026'] — разбить по пробелам
print("Привет".startswith("При")) # True — начинается с "При"?
print("файл.txt".endswith(".txt")) # True — заканчивается на ".txt"?
print("ЕГЭ2026".isdigit()) # False — состоит только из цифр?
print("2026".isdigit()) # True — а вот это да
Строки можно сравнивать и складывать:
print("яблоко" < "банан") # True — сравнение по алфавиту
print("ЕГЭ" + " " + "2026") # ЕГЭ 2026 — склейка (конкатенация)
print("ха" * 3) # хахаха — повтор
В задаче 24 часто считаем вхождения подстроки:
s = "ABCABCABC"
print(s.count("BC")) # 3 — сколько раз встречается "BC"
f-строка — это специальная строка с буквой f перед кавычками. Внутри неё в фигурных скобках {} можно подставлять переменные и выражения. Это намного удобнее, чем склеивать строку через + или str().
x = 42
y = 3.14
print(f"x = {x}, y = {y}") # x = 42, y = 3.14
print(f"сумма = {x + y}") # сумма = 45.14 (можно прямо выражения!)
Главная фишка для ЕГЭ — форматирование внутри фигурных скобок. После имени переменной ставим двоеточие и указываем формат. Это критично для задач 5, 13, 14.
Двоичное представление с ведущими нулями (нужно в задачах 5, 13, 14):
x = 7
print(f"{x:b}") # 111 — двоичное представление
print(f"{x:08b}") # 00000111 — двоичное, дополнено нулями до 8 знаков
print(f"{x:032b}") # 32-битное двоичное (используется в задаче 13 для IP)
Другие системы счисления:
print(f"{255:x}") # ff — шестнадцатеричное
print(f"{255:o}") # 377 — восьмеричное
Округление и количество знаков после запятой (полезно в задаче 27):
pi = 3.14159
print(f"{pi:.2f}") # 3.14 — два знака после запятой
print(f"{pi:.4f}") # 3.1416 — четыре знака
Пример из задачи 13: перебор IP-адресов сети, считаем те, в чьём двоичном представлении чётное число единиц.
from ipaddress import ip_network
net = ip_network('172.16.160.0/255.255.240.0', strict=False)
k = 0
for ip in net:
b = f'{int(ip):032b}' # 32-битная двоичная запись IP
if b.count('1') % 2 == 0: # если число единиц чётное
k += 1
print(k)
len(s) — длина строки (число символов).
s.count(x) — сколько раз x встречается в s.
s.find(x) — индекс первого вхождения x (или -1, если нет).
s.replace(a, b) — заменить все a на b.
s.upper() / s.lower() — верхний / нижний регистр.
s.strip() — убрать пробелы по краям.
s.split() — разбить строку в список.
s.startswith(x) / s.endswith(x) — начинается / заканчивается на x.
s.isdigit() — строка из одних цифр?
+ — склейка строк, * — повтор, in — проверка вхождения.
f"{x}" — f-строка, подставляет значение переменной.
f"{x:08b}" — двоичная запись с ведущими нулями до 8 знаков.
f"{x:.2f}" — округление до 2 знаков после запятой.
.count() считает непересекающиеся вхождения. В строке "aaa" метод .count("aa") даст 1, а не 2.
.find() возвращает -1, если ничего не нашёл, — не забывай это проверять.
Нельзя сложить строку и число: "abc" + 5 — ошибка. Нужно "abc" + str(5).
.strip(), .upper() и прочие не меняют саму строку, а возвращают новую. Пиши s = s.strip(), если хочешь сохранить результат.
В f-строке обязательна буква f перед кавычками: f"{x}", а не "{x}". Без f фигурные скобки останутся как есть.
Дроби и округление нужны, когда считаем объём памяти или делим что-то и надо округлить «вверх» или «вниз».
Вещественные числа (float) — это числа с дробной частью, например 3.14. Главная боль — округление. На ЕГЭ часто надо округлить именно вверх (потому что «памяти не хватит») или вниз.
math?Прежде чем округлять, познакомимся с библиотекой math. Простыми словами: math — это встроенный набор готовых математических инструментов Python (округление, корень, логарифм и так далее). Он уже стоит на любом компьютере — ничего скачивать не надо. Чтобы им пользоваться, в начале программы пишем подключение через import:
from math import ceil, floor # берём из math только нужные инструменты
После этой строчки команды ceil и floor доступны во всём коде. Можно подключить вообще всё сразу через from math import *, но аккуратнее брать только то, что нужно.
from math import ceil, floor
print(ceil(3.1)) # 4 — округление ВВЕРХ
print(floor(3.9)) # 3 — округление ВНИЗ
print(round(3.5)) # 4 — обычное округление
print(int(3.9)) # 3 — отбрасывает дробь (как floor для плюса)
Задача 7 или 11 — сколько байт нужно, если на символ идёт дробное число бит:
from math import ceil
symbols = 1000
bits_per = 6.5 # допустим, столько бит на символ нужно округлить
bytes_total = ceil(symbols * bits_per / 8) # округляем ВВЕРХ
print(bytes_total)
from math import ceil, floor — сначала подключаем библиотеку.
ceil(x) — округление вверх.
floor(x) — округление вниз.
round(x) — округление к ближайшему целому.
int(x) — отбрасывает дробную часть.
Деление / всегда даёт float, даже если делится нацело.
Память считаем через ceil (вверх), потому что нельзя выделить «половину байта». Простое правило: памяти не хватает — округляй вверх.
round() иногда округляет неожиданно (round(2.5) даёт 2, а не 3, — это банковское округление). На ЕГЭ лучше используй ceil/floor, чтобы не словить сюрприз.
int(-3.9) даёт -3, а floor(-3.9) даёт -4. Для отрицательных это разные вещи!
Забыл from math import ceil — получишь ошибку «name 'ceil' is not defined».
Массивы (в Python их зовут списками) — основа задач 5, 9, 14, 16, 17, 25, 26, 27. Когда надо хранить много чисел сразу — без списка никак.
Список — это как коробка с пронумерованными ячейками, куда можно сложить много предметов и обращаться к каждому по номеру. Положил числа — и работаешь с ними как с единым целым.
a = [10, 20, 30, 40] # создали список из 4 чисел
print(a[0]) # 10 — первый элемент
print(a[-1]) # 40 — последний
print(len(a)) # 4 — сколько элементов
a.append(50) # добавили 50 в конец
print(a) # [10, 20, 30, 40, 50]
Создать список из нулей:
b = [0] * 5 # [0, 0, 0, 0, 0]
В задаче 9 мы читаем числа и обрабатываем их. Превратить строку с числами в список нам поможет связка .split() (разбить по пробелам) и int() (превратить в число) — но об этом приёме подробно поговорим в главе 10. А пока просто посмотри, что со списком чисел легко работать:
a = [5, 3, 8, 1, 9] # список из 5 чисел
print(max(a)) # 9 — максимум
print(min(a)) # 1 — минимум
print(sum(a)) # 26 — сумма
print(len(a)) # 5 — сколько чисел
Иногда нужен не просто список, а таблица — список, у которого внутри лежат другие списки. Это полезно в задачах с матрицами и игровыми полями.
# Создаём «таблицу» 3x3 из нулей:
m = [[0] * 3 for _ in range(3)]
print(m)
# [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
# Обращение к элементу: сначала строка, потом столбец:
m[1][2] = 7 # во 2-й строке, 3-м столбце
print(m[1][2]) # 7
# Перебор всех элементов через два цикла:
for i in range(3):
for j in range(3):
print(m[i][j], end=' ')
print() # перевод строки после каждой строки таблицы
Внимание! Двумерный список нужно создавать только через генератор [[0]*n for _ in range(m)], а НЕ через [[0]*n]*m. Во втором варианте получаются «связанные» строки — изменишь один элемент, изменятся все одновременно. Это классическая ошибка.
# ❌ ПЛОХО — все строки указывают на один и тот же список:
m = [[0] * 3] * 3
m[0][1] = 7
print(m) # [[0, 7, 0], [0, 7, 0], [0, 7, 0]] — ВСЕ изменились!
# ✅ ХОРОШО — каждая строка независимая:
m = [[0] * 3 for _ in range(3)]
m[0][1] = 7
print(m) # [[0, 7, 0], [0, 0, 0], [0, 0, 0]] — только нужная
[1, 2, 3] — список.
a[i] — элемент по индексу (с 0!).
len(a) — длина.
a.append(x) — добавить в конец.
[0] * n — список из n нулей.
max(a), min(a), sum(a) — максимум, минимум, сумма.
[[0]*n for _ in range(m)] — двумерный список m×n.
m[i][j] — элемент 2D-списка: сначала строка, потом столбец.
Нумерация с нуля, как и у строк.
Никогда не создавай двумерный список как [[0]*n]*m — строки получатся связанными! Только через [[0]*n for _ in range(m)].
Не путай append() (добавить один элемент) и + (склеить два списка).
Это сердце задач 5, 9, 14, 16, 17, 25. «Линейный» — значит проходим по списку один раз и что-то считаем: сумму, количество, максимум по условию.
Представь, что ты идёшь вдоль полки с товарами и считаешь, например, сколько среди них красных. Идёшь по очереди, проверяешь каждый, ведёшь счётчик. Это и есть линейный алгоритм.
Классический приём — счётчик и накопитель:
a = [5, 12, 7, 20, 3, 15]
count = 0 # счётчик (сколько подходящих)
summa = 0 # накопитель суммы
for x in a: # проходим по элементам
if x > 10: # если число больше 10
count += 1 # увеличиваем счётчик
summa += x # добавляем к сумме
print(count, summa) # 3 47
Задача 9: проверяем условие для набора чисел из строки:
a = [4, 9, 2] # числа из строки файла
if sum(a) > max(a) * 2: # своё условие из задачи
print("подходит")
Счётчик: count = 0, потом count += 1.
Накопитель: summa = 0, потом summa += x.
Поиск максимума по условию — через перебор с if.
for x in a: — проходимся по значениям.
for i in range(len(a)): — проходимся по индексам (когда нужны соседи).
Забывают обнулить счётчик перед циклом — и копят мусор.
Когда нужны соседние элементы (a[i] и a[i+1]), идём по индексам, а не по значениям. И следи за границей: range(len(a)-1), иначе вылетишь за список.
Главное — отработать это на практике, тут теория быстро забывается.
Методы — это ускорители для задач 8, 9, 14, 17, 24, 25. Они заменяют целые циклы одной командой. А генераторы списков — это вообще твой главный шаблон для чтения данных из файла. Балл решает, а время на экзамене ограничено — поэтому эти приёмы экономят и то, и другое.
Метод — это встроенная суперспособность списка или строки. Не надо писать цикл для сортировки — есть .sort(). Не надо вручную резать строку по пробелам — есть .split().
Самые нужные методы списков:
a = [3, 1, 2]
a.sort() # [1, 2, 3] — сортировка по возрастанию
a.sort(reverse=True) # [3, 2, 1] — по убыванию
a.append(5) # [3, 2, 1, 5] — добавить в конец
a.count(2) # сколько раз встречается 2
a.index(2) # индекс первого вхождения числа 2
len(a) # длина списка
sum(a) # сумма всех элементов
max(a), min(a) # максимум и минимум
Магия строк для чтения данных:
s = "5 3 8 1"
parts = s.split() # ['5', '3', '8', '1'] — список строк
print(' '.join(parts)) # "5 3 8 1" — склеить список обратно в строку
А теперь — самое важное в этой главе. Генератор списка (или «списковое включение») — это способ создать список в одну строку. Звучит страшно, но на деле это просто «упакованный» цикл for. Не парься, если сразу не понятно, просто прокрути пример в голове.
Смотри, обычно мы создаём список через цикл так:
# Длинный способ — через обычный цикл:
kvadraty = [] # пустой список
for x in range(1, 6): # перебираем числа 1..5
kvadraty.append(x * x) # добавляем квадрат каждого
print(kvadraty) # [1, 4, 9, 16, 25]
А генератор делает то же самое, но в одну строку:
# Короткий способ — генератор списка:
kvadraty = [x * x for x in range(1, 6)]
print(kvadraty) # [1, 4, 9, 16, 25]
Читается справа налево: «возьми каждое x из range(1, 6) и положи в список x * x». Сравни две записи — это буквально один и тот же цикл, просто свёрнутый.
В генератор можно добавить условие через if — тогда в список попадут только подходящие элементы:
# Только чётные числа от 0 до 9:
chetnye = [x for x in range(10) if x % 2 == 0]
print(chetnye) # [0, 2, 4, 6, 8]
И вот теперь — главный приём всего ЕГЭ. Чтение чисел из строки или файла:
s = "5 3 8 1 9"
chisla = [int(x) for x in s.split()] # ['5','3',...] → [5, 3, 8, 1, 9]
print(chisla) # список настоящих чисел!
Разбираем по косточкам: s.split() разбивает строку в список строк ['5','3','8','1','9'], а генератор [int(x) for x in ...] прогоняет каждую строку через int() и делает из неё число. Заруби себе на носу: [int(x) for x in ...] — это твой пропуск к задачам 9 и 17.
Чтение чисел из файла — стандартный шаблон задачи 9, 17:
f = open("17.txt")
s = [int(x) for x in f] # читаем все числа в список (по одному в строке)
s.sort() # сортируем
print(s[-1]) # самое большое
.split() — разбить строку по пробелам в список.
' '.join(list) — склеить список в строку.
.sort() — отсортировать (меняет сам список!).
sorted(a) — вернуть новый отсортированный список.
.count(x), .index(x), .append(x) — посчитать / найти / добавить.
len(a), sum(a), max(a), min(a) — длина, сумма, макс, мин.
[int(x) for x in ...] — генератор: превратить строки в числа.
[x for x in ... if условие] — генератор с фильтром.
После .split() элементы — это строки, а не числа! Нужно превращать через int(). Вот тут надо быть очень аккуратным, иначе получишь ошибку при сравнении.
.sort() меняет сам список и возвращает None. Не пиши a = a.sort() — потеряешь данные! Если нужен новый список — бери sorted(a).
В генераторе не путай порядок: сначала что кладём (int(x)), потом откуда берём (for x in ...), потом условие (if ...).
Генератор [int(x) for x in s] — запомни его как родного, это твой главный шаблон для чтения данных.
База для задач 9, 17, 24, 26, 27. На ЕГЭ почти все «тяжёлые» задачи начинаются с того, что нужно прочитать данные из текстового файла. Если ты не умеешь открывать файл — половина задач для тебя закрыта.
Файл — это просто длинный текст, лежащий на диске. Python умеет его открыть и читать построчно (как книжку) или сразу всё целиком. Главная команда — open().
Все задачи ЕГЭ сводятся к одному из трёх вариантов записи чисел в файле. Запомни эти шаблоны — копируешь и подставляешь свою обработку.
Шаблон 1. По одному числу в строке (задачи 9, 17).
f = open("17.txt")
s = [int(x) for x in f] # каждая строка → число, всё в список
print(len(s), max(s)) # сколько чисел, максимум
Тут генератор пробегает по всем строкам файла и превращает каждую в число. Это самый частый случай.
Шаблон 2. Числа через пробел в одной строке (или несколько чисел на строку).
f = open("9.txt")
for line in f: # перебираем строки одну за другой
chisla = [int(x) for x in line.split()] # разбили строку по пробелам
# дальше работаем со списком chisla
if sum(chisla) > 100:
print(chisla)
Каждая строка превращается в свой маленький список чисел. Это шаблон задачи 9, где в каждой строке файла лежит набор чисел (например, длины сторон треугольника).
Шаблон 3. Одна гигантская строка (задача 24).
a = open("24.txt").readline() # читаем строку целиком в переменную a
print(len(a)) # длина строки — десятки/сотни тысяч символов
Метод .readline() считывает первую (и единственную) строку файла. После этого работаешь со строкой как обычно — индексы, срезы, методы.
Задача 17: найти количество пар соседних чисел, сумма которых делится на максимальный элемент, оканчивающийся на 3.
a = open("17.txt")
s = [int(x) for x in a] # шаблон 1: числа в столбик
m3 = max([x for x in s if x % 10 == 3]) # макс. элемент, оканчивающийся на 3
k = 0
for i in range(len(s) - 1): # перебираем пары соседей
if (s[i] + s[i+1]) % m3 == 0:
k += 1
print(k)
f = open("file.txt") — открыть файл.
[int(x) for x in f] — все числа из файла в список (по одному на строку).
f.readline() — прочитать одну строку.
for line in f: — пройти по строкам файла.
line.split() — разбить строку по пробелам.
line.strip() — убрать пробелы и переводы строки по краям (на всякий случай).
Не забывай преобразование int()! Без него ты будешь сравнивать строки, и "10" < "2" даст True (по алфавиту!).
В каждой строке файла в конце есть \n (символ перевода строки). int("5\n") работает нормально, но len(line) будет на 1 больше ожидаемого.
Файл открывается один раз — после полного прохода он «исчерпан». Если нужно пройти ещё — открой его снова.
На ЕГЭ ставь файл рядом со скриптом, тогда хватит просто open("17.txt") без полного пути.
На ЕГЭ по информатике можно вполне обойтись без словарей — почти все задачи решаются через списки, генераторы и циклы. Но если ты хочешь стать программистом, словари — это база, без которой никуда. Поэтому мы дадим короткий обзор: что это, зачем нужно, как пользоваться.
Словарь (dict) — это структура, где хранятся пары «ключ → значение». В отличие от списка, где элементы лежат под номерами (a[0], a[1]), здесь ты обращаешься по любому ключу: имени, букве, числу.
Аналогия из жизни: записная книжка. Имя → телефон, артикул → цена, слово → перевод.
d = {} # пустой словарь
d["Аня"] = 89001234567 # добавили запись: ключ "Аня" → значение телефон
d["Боря"] = 89009876543
print(d["Аня"]) # 89001234567 — берём по ключу
Можно создавать сразу с записями:
d = {"яблоко": 50, "груша": 80, "слива": 30}
print(d["груша"]) # 80
Подсчёт встречаемости — самый частый случай. Например, посчитать, сколько раз встречается каждая буква в строке:
s = "abracadabra"
d = {}
for ch in s:
d[ch] = d.get(ch, 0) + 1 # увеличиваем счётчик ключа ch на 1
print(d)
# {'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1}
Метод .get(ключ, 0) возвращает значение по ключу. Если ключа ещё нет в словаре — возвращает 0 (или другое значение, которое ты задал). Это удобно, чтобы не проверять каждый раз вручную.
d = {"яблоко": 50, "груша": 80, "слива": 30}
for k in d: # перебор ключей
print(k, d[k])
for k, v in d.items(): # перебор пар (ключ, значение)
print(k, "стоит", v)
d = {} — пустой словарь.
d[k] = v — добавить / поменять значение по ключу.
d[k] — получить значение по ключу (ошибка, если ключа нет).
d.get(k, 0) — получить значение, или 0, если ключа нет.
k in d — есть ли ключ в словаре?
d.items() — перебрать пары (ключ, значение).
d.keys() — список ключей; d.values() — список значений.
len(d) — сколько пар в словаре.
Обращение по несуществующему ключу d["нет"] даёт ошибку. Используй .get(), если не уверен, есть ли ключ.
Ключи в словаре уникальны: если присвоить значение по существующему ключу — старое затрётся.
Ключом может быть число, строка, кортеж, но НЕ список (списки нельзя использовать как ключ).
Для подсчёта частот в задачах ЕГЭ можно обойтись и без словаря (через s.count(x)), но словарь работает в разы быстрее на больших данных.
Функции и особенно рекурсия — это ключ к задачам 16, 19-21, 23, 25, 27. В 16-й задаче рекурсивная функция задана прямо в условии, и тебе надо её просто аккуратно перенести в код.
Функция — это твой собственный мини-инструмент, которому ты дал имя. Написал один раз — используешь сколько хочешь. Рекурсия — это когда функция вызывает саму себя. Звучит странно, но на деле это просто «матрёшка»: чтобы посчитать большое, функция считает чуть меньшее, и так до самого простого случая.
Обычная функция:
def kvadrat(x): # def — определяем функцию с именем kvadrat
return x * x # return — что функция возвращает
print(kvadrat(5)) # 25
Рекурсивная функция (вызывает себя):
def F(n):
if n <= 1: # базовый случай — когда остановиться
return 1
return n * F(n - 1) # функция вызывает саму себя для n-1
print(F(5)) # 120 (это 5*4*3*2*1)
В задаче 16 функцию дают прямо в условии. Например: F(n) = n + F(n-2), если n > 0, иначе 0. Переносим один в один:
def F(n):
if n > 0:
return n + F(n - 2)
else:
return 0
print(F(10)) # 10+8+6+4+2 = 30
def имя(параметры): — определяем функцию.
return — возвращает результат (и завершает функцию).
Рекурсия = функция вызывает саму себя.
В рекурсии обязателен базовый случай — условие выхода.
Без базового случая будет бесконечная рекурсия и ошибка.
В задаче 16 просто аккуратно переписывай формулу из условия.
Забыл базовый случай — рекурсия уйдёт в бесконечность, и Python выдаст RecursionError.
Путают порядок условий в задаче 16. Переписывай формулу буквально, не упрощая.
Если рекурсия глубокая, Python может «не потянуть». Тогда выручает lru_cache или цикл — подробнее в главе про библиотеки.
Сложность критична в задачах 26 и 27 — там файлы огромные, и если твой код тупой, он будет считать вечность. На экзамене у тебя нет «вечности».
Сложность алгоритма — это про то, насколько быстро работает твой код, когда данных становится много. Если ты на каждый элемент проходишь весь список заново — это медленно (квадратичная сложность). Если проходишь данные один раз — быстро (линейная).
Медленно — два вложенных цикла (для каждого элемента смотрим все остальные):
# МЕДЛЕННО: ~n*n операций
for i in range(len(a)):
for j in range(len(a)):
...
Быстро — один проход:
# БЫСТРО: ~n операций
summa = 0
for x in a:
summa += x
В задаче 24 файл — это гигантская строка на сотни тысяч символов. Решать «в лоб», вырезая и пересчитывая куски на каждом шаге, — слишком медленно. Спасает приём «скользящее окно»: идём по строке один раз, набираем символы в s, а как только условие нарушилось — отрезаем лишнее слева. Один проход вместо вложенных циклов.
a = open("24.txt").readline().strip() # читаем длинную строку
s = '' # наше "окно"
m = 0 # лучший ответ (макс. длина)
k = 0 # счётчик нужной подстроки внутри окна
for i in a: # идём по строке ОДИН раз
s += i # добавляем символ справа
if s[-4:] == '2025': # появилась подстрока "2025"?
k += 1
while k > 90: # если её стало слишком много
if s[:4] == '2025': # отрезаем слева
k -= 1
s = s[1:]
m = max(m, len(s)) # запоминаем макс. длину окна
print(m)
Один цикл по данным — это линейная сложность (быстро).
Два вложенных цикла — квадратичная (медленно на больших данных).
В задаче 24 спасает «скользящее окно» — один проход с добавлением справа и отрезанием слева.
Используй словари (dict) для быстрого доступа вместо повторного перебора.
Если код «думает» больше пары секунд на больших данных — почти всегда дело в лишнем вложенном цикле.
Решение «в лоб» в задаче 24 не проходит по времени. Прокачиваем этот навык на задачах из нашего курса — там разбираем «скользящее окно» по шагам.
Не храни в памяти весь огромный файл, если можно идти по строкам по одной.
Сначала отладь алгоритм на маленьком примере, а потом запускай на большом файле.
Готовые библиотеки экономят тебе время и нервы. На ЕГЭ разрешено их использовать, так что грех не пользоваться. В этой главе — все библиотеки, которые реально встречаются на экзамене. Изучи внимательно, какая где выстрелит, — и половина второй части станет проще.
Если по-простому: библиотека (её ещё зовут модуль) — это набор готовых инструментов, которые кто-то уже написал за тебя. Тебе надо только подключить её в начале программы через import и пользоваться. Зачем изобретать велосипед?
Подключать можно тремя способами:
from math import ceil # берём из math конкретный инструмент ceil
from math import * # берём из math ВСЁ сразу
import math # подключаем целиком, потом пишем math.ceil(...)
На ЕГЭ удобнее первый или второй вариант — тогда пишешь просто ceil(...), без приставки math..
math — математика (задачи 7, 11, 14, 16, 25, 27)Самая частая библиотека. Нужна почти везде, где есть вычисления.
from math import ceil, floor, sqrt, gcd, log, log2, factorial, pi
Округление:
print(ceil(3.2)) # 4 — вверх
print(floor(3.8)) # 3 — вниз
print(round(3.5)) # 4 — к ближайшему (банковское!)
Корни и степени:
print(sqrt(16)) # 4.0 — квадратный корень
print(16 ** 0.5) # 4.0 — то же самое через степень
print(pow(2, 10)) # 1024 — возведение в степень (как 2**10)
Делимость и НОД:
print(gcd(12, 18)) # 6 — наибольший общий делитель
# В Python 3.9+ можно gcd с несколькими: gcd(12, 18, 24) → 6
Логарифмы (главный инструмент задачи 11):
print(log2(8)) # 3.0 — логарифм по основанию 2
print(log(8, 2)) # 3.0 — логарифм по любому основанию
print(log(100, 10)) # 2.0 — десятичный
log2 — твой друг в задаче 11: именно через него считают, сколько бит нужно на символ (ceil(log2(N))).
Факториал и константы (изредка — задача 8 «руками», задача 27 геометрия):
print(factorial(5)) # 120 — это 5! = 5*4*3*2*1
print(pi) # 3.141592653589793
Полная шпаргалка по math:
ceil(x) / floor(x) — округление вверх / вниз.
sqrt(x) — корень квадратный.
gcd(a, b) — НОД двух (или больше) чисел.
log2(x) — логарифм по основанию 2; log(x, b) — по основанию b.
factorial(n) — n! (факториал).
pi, e — константы.
pow(a, b) — степень (то же, что a ** b).
itertools — перебор комбинаций (задачи 8, 15)Спасение для задачи 8 (комбинаторика). А combinations дополнительно выручает в задаче 15 на отрезки.
product — все слова с повторами:
from itertools import product
for p in product('АБ', repeat=2):
print(''.join(p)) # АА, АБ, БА, ББ
permutations — перестановки без повторов:
from itertools import permutations
for p in permutations('АБВ', 2):
print(''.join(p)) # АБ, АВ, БА, БВ, ВА, ВБ
combinations — сочетания (порядок неважен) — мегаполезны в задаче 15 на отрезки:
from itertools import combinations
# Все пары чисел из списка — БЕЗ повторов и без учёта порядка:
for c in combinations([1, 2, 3, 4], 2):
print(c) # (1,2), (1,3), (1,4), (2,3), (2,4), (3,4)
В задаче 15 на отрезки combinations помогает перебрать все пары «концов отрезков». Например, у тебя есть набор граничных точек, и нужно проверить все варианты, какие две взять как левую и правую границу:
from itertools import combinations
# границы отрезков из условия + контрольные точки рядом
gran = [10, 15, 20, 30]
toch = []
for g in gran:
toch += [g - 0.5, g, g + 0.5]
# Перебираем все пары точек как (левая, правая) граница искомого отрезка:
for a1, a2 in combinations(toch, 2):
if a1 < a2:
# тут проверяем условие задачи
pass
Полная шпаргалка по itertools:
product(s, repeat=n) — все слова длины n с повторами (главное для задачи 8).
permutations(s, n) — все перестановки длины n без повторов.
combinations(s, n) — все сочетания длины n (порядок неважен, без повторов).
combinations_with_replacement(s, n) — сочетания с повторами.
В задаче 8 почти всегда нужен product. В 15 на отрезки — combinations.
functools — кэширование рекурсии (задача 16)Выручает в задаче 16, когда рекурсия слишком глубокая и тормозит. @lru_cache запоминает уже посчитанные значения, чтобы не считать их заново.
from functools import lru_cache
@lru_cache(10000) # волшебная строчка над функцией
def G(n):
if n <= 20:
return n + 2
return G(n - 3) + 1
print(G(37811)) # считается мгновенно, без зависаний
Просто ставь @lru_cache(10000) над рекурсивной функцией — и она перестанет тупить на больших числах. Число в скобках — это размер кэша; обычно ставят 10000 или больше, можно и @lru_cache(maxsize=None) для неограниченного.
Полная шпаргалка по functools:
@lru_cache(N) — кэшировать результаты функции, держать не более N значений.
@lru_cache(maxsize=None) — без ограничения по размеру.
Ставится прямо над функцией, без пустых строк.
ipaddress — сети (задача 13)Готовый инструмент для работы с IP-адресами и масками. Сам считает адрес сети, broadcast и диапазон.
from ipaddress import ip_network
net = ip_network('192.168.1.10/255.255.255.0', strict=False)
print(net[0]) # адрес сети (первый адрес)
print(net[-1]) # широковещательный адрес (последний)
print(net[1]) # минимальный адрес для компьютера
print(net[-2]) # максимальный адрес для компьютера
print(net.netmask) # маска сети
print(net.num_addresses)# всего адресов в сети
Главное запомнить: net[0] — сеть, net[-1] — broadcast, net[-2] — самый большой адрес ПК. strict=False (или просто 0) обязателен, иначе будет ошибка.
Перебор всех IP в сети с условием:
k = 0
for ip in net:
b = f'{int(ip):032b}' # двоичное представление IP (32 бита)
if b.count('1') % 2 == 0: # своё условие из задачи
k += 1
print(k)
Полная шпаргалка по ipaddress:
ip_network('адрес/маска', strict=False) — создать объект сети.
net[0] — адрес сети, net[-1] — broadcast.
net[1] — минимальный адрес ПК, net[-2] — максимальный.
net.netmask — маска, net.num_addresses — всего адресов.
net.num_addresses - 2 — количество узлов (без сети и broadcast).
Для маски через слэш можно писать сразу число единиц: '1.2.3.4/24'.
re — регулярные выражения (задача 24)Регулярки — мощный способ искать шаблоны в длинной строке. Главная функция — finditer, она проходит по всем совпадениям в строке.
from re import finditer
s = "A12B345C6"
for m in finditer(r'[0-9]+', s): # ищем все группы цифр
print(m.group()) # 12, 345, 6
print(m.start(), m.end()) # индексы начала и конца совпадения
Шпаргалка по символам регулярок:
Символьные классы:
[ABC] — один из символов A, B, C.
[A-Z] — диапазон A–Z.
[^ABC] — любой символ, кроме A, B, C.
. — любой символ.
Квантификаторы (сколько раз повторяется):
* — 0 и больше повторов.
+ — 1 и больше.
? — 0 или 1.
{n} — ровно n.
{n,m} — от n до m.
Группировка и альтернатива:
(AB)+ — пара AB подряд.
AB|CD — AB или CD.
Экранирование (если нужен сам спецсимвол): \*, \+, \., \(, \) и т.д.
Жадные и ленивые квантификаторы — важная тема для задачи 24!
По умолчанию *, +, ? и {n,m} — жадные: захватывают как можно больше символов. Если добавить ? после квантификатора — он становится ленивым и захватывает как можно меньше.
from re import findall
s = "<a><b><c>"
# Жадный — захватит ВСЁ от первого < до последнего >:
print(findall(r'<.+>', s)) # ['<a><b><c>']
# Ленивый — захватит МИНИМУМ символов между < и >:
print(findall(r'<.+?>', s)) # ['<a>', '<b>', '<c>']
Когда это критично: при поиске чисел или подстрок между разделителями (например, римские числа в задаче 24). Если ты ищешь по жадному шаблону — рискуешь склеить несколько соседних совпадений в одно. Лень тут лечит.
Пример на ЕГЭ — 14-ричное число без ведущего нуля, заканчивающееся чётной цифрой:
r'[1-9A-D][0-9A-D]*[02468AC]'
Полная шпаргалка по re:
finditer(pattern, s) — итератор по всем совпадениям.
findall(pattern, s) — список всех совпадений сразу.
search(pattern, s) — первое совпадение или None.
fullmatch(pattern, s) — строка целиком подходит под шаблон?
m.group() — текст совпадения.
m.start() / m.end() — индексы начала/конца совпадения.
Префикс r'' перед строкой — чтобы \ понимались как символы регулярки, а не Python.
Жадность: * + ? {n,m} — жадные. Добавь ? после, чтобы сделать ленивыми: *?, +?, ??, {n,m}?.
fnmatch — маски чисел (задача 25)Удобно проверять, подходит ли число под «шаблон с дырками».
from fnmatch import fnmatch
print(fnmatch("54213", "54?1?")) # True — ? это один любой символ
print(fnmatch("12700", "1*0")) # True — * это любые символы (в т.ч. ноль)
print(fnmatch("12345", "1?345")) # True — ? на месте одной цифры
Шаблон решения задачи 25 (маска + шаг):
Задача обычно звучит так: «среди чисел вида (что-то, например, кратных 7) найди первые 5 чисел в диапазоне, подходящих под маску 1?2*7».
from fnmatch import fnmatch
k = 0
for n in range(100000, 1000000, 7): # кратные 7 в диапазоне
if fnmatch(str(n), "1?2*7"): # подходит ли под маску
print(n, n // 7) # выводим число и частное
k += 1
if k == 5: break # нужно только 5
Шаблон с поиском делителей (задача 25 на делители):
Часто задача 25 — про делители: «найти числа, у которых есть делитель определённого вида». Шаблон через функцию:
def div(n): # поиск нужного делителя у n
for d in range(2, int(n**0.5) + 1):
if n % d == 0:
# тут проверка условия из задачи (например, оканчивается на 7)
if d % 10 == 7: return d
if (n // d) % 10 == 7: return n // d
return 0 # не нашли — возвращаем 0
k = 0
for n in range(1000001, 10**10):
M = div(n)
if M > 0:
print(n, M)
k += 1
if k == 5: break
Запомни: для поиска делителей хватает перебора до √n (range(2, int(n**0.5)+1)) — это в разы быстрее, чем до n.
Полная шпаргалка по fnmatch:
fnmatch(строка, шаблон) — True/False.
? — ровно один любой символ.
* — любое число символов (включая 0).
[123] — один из перечисленных символов.
В задаче 25: главные «герои» — ? и *. Проверяй число через str(n), потому что fnmatch работает только со строками.
sys — лимит рекурсии (НЕ рекомендуем на ЕГЭ)Иногда рекурсия в задаче 16 такая глубокая, что Python ругается RecursionError. По умолчанию лимит около 1000 вызовов. Существует команда setrecursionlimit, которая позволяет его поднять:
from sys import setrecursionlimit
setrecursionlimit(1000000) # теоретически разрешает миллион вызовов
Но мы не советуем использовать это на ЕГЭ. Поднятие лимита часто работает нестабильно: Python может «упасть» прямо на проверке, и ты потеряешь баллы. На экзаменационном ПК поведение непредсказуемо.
Что использовать вместо этого:
@lru_cache из functools — кэшируем результаты, рекурсия не уходит глубоко.
Цикл вместо рекурсии — заполняем массив F[n] от начала к концу. Самый надёжный способ для задачи 16, особенно с большими n.
# Безопасный шаблон через массив (без рекурсии):
F = [0] * 100000
for n in range(100000):
if n < 10: F[n] = n + 2
else: F[n] = F[n-3] + 1
print(F[37811])
turtle — графика (задача 6)В задаче 6 про исполнителя Черепаху ты руками считать точки внутри фигуры не сможешь — фигура бывает сложной. Поэтому используется хитрый приём: Python рисует фигуру за тебя, а потом «закрашивает» весь экран красными точками по узлам сетки. Точки, которые попали внутрь фигуры, легко посчитать визуально (или они отчётливо видны на белом фоне).
Идея простая:
Переписываем алгоритм Черепахи из условия (вперёд / поворот / повтори).
Поднимаем перо и обходим все целые точки на плоскости через двойной цикл, ставим в каждой маленькую красную точку.
Открываем картинку, считаем глазами точки внутри фигуры (включая на границе — зависит от условия задачи).
from turtle import *
tracer(0) # отключаем анимацию (рисует мгновенно)
m = 15 # масштаб (один шаг условия = m пикселей)
# 1. Рисуем фигуру по алгоритму из условия задачи:
for i in range(4):
fd(3 * m) # forward — вперёд
rt(90) # right — поворот направо
fd(5 * m)
lt(90) # left — поворот налево
# 2. Поднимаем перо и ставим точки сетки по всему полю:
up() # поднять перо (двигаться без рисования)
for x in range(-20, 20):
for y in range(-20, 20):
goto(x * m, y * m) # переходим в узел сетки
dot(3, "red") # ставим маленькую красную точку
update() # показать всё нарисованное сразу
exitonclick() # окно закроется по клику мыши
Что делать дальше: в открывшемся окне ты видишь фигуру и решётку из красных точек. Считаешь точки внутри фигуры (и на её сторонах, если так сказано в условии) — это и есть ответ.
Важная мелочь: диапазон range(-20, 20) подбирай так, чтобы сетка точно покрывала всю фигуру. Если фигура большая — расширяй до range(-50, 50). Масштаб m тоже подбирай: при m = 15 пиксели не слипаются и точки хорошо видны.
Полная шпаргалка по turtle:
fd(n) / forward(n) — вперёд на n шагов.
bk(n) / backward(n) — назад на n шагов.
rt(угол) / right(угол) — поворот направо на угол градусов.
lt(угол) / left(угол) — поворот налево.
up() / penup() — поднять перо (рисование выключено).
down() / pendown() — опустить перо (снова рисуем).
goto(x, y) — переместиться в точку (x, y).
dot(размер, цвет) — поставить точку.
tracer(0) — отключить анимацию (быстрее рисует).
update() — показать всё, что нарисовано.
exitonclick() — закрыть окно по клику.
Запомни: углы в rt/lt — в градусах. Чаще всего на ЕГЭ это 90, 45, 60.
dist (задача 27)В задаче 27 про звёзды нужно считать расстояние между точками на плоскости. Своя функция dist — must have в шаблоне.
def dist(a, b):
x1, y1 = a[0], a[1]
x2, y2 = b[0], b[1]
return ((x2 - x1) ** 2 + (y2 - y1) ** 2) ** 0.5
print(dist([0, 0], [3, 4])) # 5.0 — классическая «3-4-5» тройка
Формула из условия задачи 27: d(A, B) = √((x2 − x1)² + (y2 − y1)²). Это обычная теорема Пифагора.
А ещё в Python есть встроенная math.dist:
from math import dist
print(dist([0, 0], [3, 4])) # 5.0 — то же самое, но готовое
Центр кластера (медоид) — точка с минимальной суммой расстояний до всех остальных:
def centr(K): # K — список точек кластера
best = None
for i in K:
s = sum(dist(i, j) for j in K)
if best is None or s < best[0]:
best = [s, i]
return best[1]
Эта пара функций (dist + centr) — твой стандартный шаблон для задачи 27. Зубрить нужно вместе.
from math import ceil, floor, sqrt, gcd, log2, factorial, pi, dist — математика и геометрия.
from itertools import product, permutations, combinations — комбинаторика (8, 15).
from functools import lru_cache — кэш рекурсии (16).
from ipaddress import ip_network — сети (13).
from re import finditer, findall, search — регулярки (24).
from fnmatch import fnmatch — маски (25).
from turtle import * — графика, задача 6 (Черепаха).
Забывают подключить модуль через import — и получают ошибку «name is not defined».
product('АБ', repeat=2) даёт кортежи, а не строки. Склеивай через ''.join().
log2 иногда даёт неточный результат из-за float. Для количества бит надёжнее ceil(log2(...)).
В ipaddress не забудь strict=False (или 0) — иначе ошибка на адресе узла.
@lru_cache ставится прямо над функцией, без пустой строки между ними.
В combinations важен порядок аргументов: первый — откуда выбираем, второй — сколько.
В turtle обязательно tracer(0) + update(), иначе будет рисовать долго и неудобно.
fnmatch принимает только строки: число надо превращать через str(n).
+ - * / — сложение, вычитание, умножение, деление (дробь).
// — целочисленное деление, % — остаток, ** — степень.
if / elif / else — ветвление (в цепочке срабатывает одна ветка).
== — сравнение, = — присваивание.
and, or, not — логика.
for i in range(a, b, step): — известное число повторов.
range(a, b) — от a до b-1; range(b, a, -1) — назад.
for x in spisok: — по значениям списка/строки.
while условие: — пока условие верно.
s[i] — символ, s[a:b] — срез, s[::-1] — разворот.
len(s), .count(), .find(), .replace(), .upper(), .lower().
.strip(), .split(), .startswith(), .endswith(), .isdigit().
' '.join() — склеить список в строку.
f"{x}" — подставить значение переменной.
f"{x:08b}" — двоичная запись с ведущими нулями до 8 знаков.
f"{x:032b}" — 32-битное двоичное (задача 13, IP-адреса).
f"{x:.2f}" — округление до 2 знаков после запятой (задача 27).
f"{x:x}" — шестнадцатеричное; f"{x:o}" — восьмеричное.
[1,2,3], a[i], len(a), .append(), .index(), .count(), [0]*n.
max(a), min(a), sum(a), .sort(), sorted(a).
[int(x) for x in s] — генератор: чтение чисел.
[x for x in a if условие] — генератор с фильтром.
[[0]*n for _ in range(m)] — двумерный список m×n.
d = {}, d[k] = v, d[k] — создать, добавить, получить.
d.get(k, 0) — получить значение или 0, если ключа нет.
for k, v in d.items(): — перебор пар.
ceil() — вверх, floor() — вниз, round() — к ближайшему, int() — отбросить дробь.
def имя(параметры): return ...
Рекурсия = функция вызывает себя + базовый случай.
from math import ceil, floor, sqrt, gcd, log2, factorial, pi, dist — математика.
from itertools import product, permutations, combinations — комбинаторика (8, 15).
from functools import lru_cache — кэш рекурсии (16).
from ipaddress import ip_network — сети (13).
from re import finditer, findall, search — регулярки (24).
from fnmatch import fnmatch — маски (25).
from turtle import * — графика, задача 6 (Черепаха).
# 1. По одному числу в строке (задачи 9, 17):
f = open("file.txt")
s = [int(x) for x in f]
# 2. Числа через пробел в каждой строке (задача 9):
f = open("file.txt")
for line in f:
chisla = [int(x) for x in line.split()]
# 3. Одна гигантская строка (задача 24):
a = open("file.txt").readline()
В итоге: выучи эту шпаргалку — и ЕГЭ у тебя в кармане. Главное — отработать это на практике. Удачи на экзамене, ты справишься!