Введение
Ты в 11-м классе, открываешь КИМ ЕГЭ по информатике и видишь задание с файлом на 100 000 чисел. С чего начать — непонятно? Знакомая ситуация. Многие теряют баллы в задании № 17 просто потому, что путаются в индексах или забывают про отрицательные числа.
На самом деле задачи на обработку числовых последовательностей (пары и тройки элементов) — одна из самых понятных и шаблонных тем в школьной информатике. Стоит разобраться в базовых принципах работы с массивами — и такие задания начинают решаться за три-четыре минуты.
В этой статье разберём ключевую теорию, покажем универсальный шаблон решения и обсудим типичные ловушки.
Массивы и последовательности чисел
В Python числовая последовательность из файла обычно считывается в список (массив). Массив — это просто набор данных, где у каждого элемента есть свой порядковый номер (индекс). Важно помнить: индексы в Python начинаются с нуля.
Первое, что мы делаем в задаче, — забираем числа из текста в память программы:
a = [int(x) for x in open(’17.txt’)]
Эта строчка с объяснением означает: «Пройдись по всем строкам файла 17.txt, преврати каждую строку в целое число (int) и положи в список a».
Вычисление обобщённых характеристик
Часто перед тем, как искать пары, нам нужно узнать что-то про весь массив целиком.
- Минимальный и максимальный элементы. Находятся встроенными функциями min(a) и max(a).
- Сумма всех элементов. Функция sum(a).
- Количество элементов по условию. Например, нам нужно найти количество всех элементов, которые оканчиваются на 5.
Линейный поиск заданного значения в массиве чаще всего реализуется через генераторы списков. Это и есть алгоритм с однократным просмотром массива: мы пробегаемся по списку всего один раз, фильтруя нужные данные.
Пример: найдём минимальный элемент, который делится на 15.
min_val = min([x for x in a if x % 15 == 0])
Сортировка одномерного массива
Иногда (редко в задании № 17, но в других, например в № 9 или 26) массив нужно отсортировать по возрастанию. Для этого используется метод .sort().
a.sort() # Массив ‘a’ теперь отсортирован от меньшего к большему
Пары, тройки и индексы
Если мы ищем элементы, которые стоят рядом, нам нужен цикл по индексам i.
- Текущий элемент: a[i].
- Следующий элемент: a[i+1].
- Элемент через один: a[i+2].
Чтобы программа не выдала ошибку IndexError (выход за границы массива), мы должны правильно настроить цикл:
- Для пар цикл идёт до последнего минус один: for i in range(len(a) — 1)
- Для троек цикл идёт до последнего минус два: for i in range(len(a) — 2)
Пошаговый алгоритм решения задания № 17
Чтобы написать правильный код для любой задачи этого типа, используй этот шаблон действий:
- Считай данные из файла в массив.
- Сделай первый проход (линейный поиск), если задача требует найти какую-то глобальную переменную (например, максимальный элемент, который оканчивается на 13).
- Создай переменные для ответа: счётчик count = 0 и переменную для максимальной/минимальной суммы (например, max_sum = -10**10, min_sum = 10**10).
- Запусти цикл по индексам (до len(a)-1 для пар или len(a)-2 для троек).
- Проверь условия для текущей группы элементов с помощью if.
- Если условие выполняется, обнови ответы (увеличь счётчик, обнови максимальную/минимальную сумму).
- Выведи результат.
Разбор задач из экзамена
Давай посмотрим, как решать реальные задачи, применяя наш алгоритм.
Работа с парами
Условие
В файле содержится последовательность чисел от 1 до 100 000. Определите количество пар последовательности, в которых только один из элементов является двузначным числом, а сумма элементов пары кратна минимальному двузначному элементу всей последовательности. В ответе запишите количество таких пар, затем максимальную из сумм элементов таких пар. Пара — это два идущих подряд элемента.
Шаги 1 и 2. Считаем файл и ищем минимальный двузначный элемент.
a = [int(x) for x in open(’17.txt’)]
# Двузначные числа лежат в диапазоне от 10 до 99
min_double = min([x for x in a if 10 <= abs(x) <= 99])
Почему abs(x)? Хотя в условии сказано, что числа от 1, привыкай брать модуль. Если в файле будут отрицательные числа, −15 — это тоже двузначное число.
Шаг 3. Задаём переменные для ответа.
count = 0
max_sum = -10**10 # Берём очень маленькое число для старта
Шаги 4–6. Запускаем алгоритм обработки пар. Нам нужно, чтобы строго один элемент был двузначным. Самый элегантный способ в Python — сложить логические условия (истина = 1, ложь = 0).
for i in range(len(a) — 1):
# Проверяем оба элемента пары на «двузначность»
cond1 = 10 <= abs(a[i]) <= 99
cond2 = 10 <= abs(a[i+1]) <= 99
# «Только один» означает, что сумма этих истин равна 1
if cond1 + cond2 == 1:
# Проверяем второе условие: сумма кратна min_double
if (a[i] + a[i+1]) % min_double == 0:
count += 1
max_sum = max(max_sum, a[i] + a[i+1])
print(count, max_sum)
Работа с тройками
Условие
В файле последовательность чисел до 100 000. Определите количество троек элементов, в которых ровно два из трёх элементов являются трёхзначными числами, а сумма элементов тройки не больше максимального элемента последовательности, оканчивающегося на 13. Запишите количество троек и максимальную сумму их элементов.
Шаги 1–3. Подготовка.
a = [int(x) for x in open(’17.txt’)]
# Ищем максимальный элемент, который оканчивается на 13.
# Окончание числа проверяем через остаток от деления модуля числа на 100. Обязательно берём модуль abs(), так как у отрицательных чисел остаток от деления вычисляется по иным правилам.
max_13 = max([x for x in a if abs(x) % 100 == 13])
count = 0
max_sum = -10**10
Шаги 4–7. Цикл для троек.
# Для троек идём до len(a) — 2!
for i in range(len(a) — 2):
# Проверяем на трёхзначность каждый элемент (от 100 до 999)
# Складываем условия и проверяем, что их ровно 2
three_digit_count = (100 <= abs(a[i]) <= 999) + \
(100 <= abs(a[i+1]) <= 999) + \
(100 <= abs(a[i+2]) <= 999)
if three_digit_count == 2:
current_sum = a[i] + a[i+1] + a[i+2]
# Второе условие: сумма не больше max_13
if current_sum <= max_13:
count += 1
max_sum = max(max_sum, current_sum)
print(count, max_sum)
Комментарий: мы использовали \ для переноса длинной строки. Логика условие1 + условие2 + условие3 == 2 избавляет нас от написания километровых проверок через and и or.
Типичные ошибки
Здесь теряют баллы в 90% случаев. Проверяй себя по этому списку:
- Выход за границы массива (IndexError).
- Как нельзя: писать for i in range(len(a)) при поиске пар.
- Как нужно: для пар range(len(a)-1), для троек range(len(a)-2).
- Почему: если i станет последним индексом списка, вызов a[i+1] попытается получить элемент, которого не существует. Программа экстренно завершится.
- Остаток от деления отрицательных чисел.
- Как нельзя: x % 10 == 3 (если x может быть отрицательным). Дело в том, что в Python -13 % 10 выдаст 7, а не 3.
- Как нужно: abs(x) % 10 == 3. Сначала отбрасываем знак модулем, потом смотрим окончание.
- Длина числа (двузначные, трёхзначные).
- Как нельзя: len(str(x)) == 2. Если x = -15, программа переведёт его в строку «-15», длина которой равна 3 (минус тоже символ).
- Как нужно: математическое сравнение 10 <= abs(x) <= 99 или же len(str(abs(x))) == 2, с помощью abs() отбрасываем знак у числа и далее переводим в строку для получения длины.
- Поиск начального максимума.
- Как нельзя: max_sum = 0. Если все подходящие суммы в файле окажутся отрицательными (например, наибольшая будет -15), в ответе выведется 0 — и ответ будет неверным.
- Как нужно: объявляем переменную очень маленьким числом, например max_sum = -10**10, или сохраняем суммы в отдельный массив и в конце применяем функцию max(sums_list). Аналогично для нахождения минимального значения объявляем переменную очень большим числом.
Заключение
Подведём итог.
- Разбивай решение на два прохода, если нужно найти общее свойство массива (минимум, максимум, среднее): сначала находишь его, затем работаешь с парами или тройками.
- Следи за индексами: для пар — len(a) — 1, для троек — len(a) — 2.
- Используй модуль abs(x), чтобы корректно работать с отрицательными числами — особенно перед операциями с остатком (%) и проверкой разрядности.
- Упрощай условия: вместо громоздких and/or удобно использовать сумму логических выражений — это снижает риск ошибок.
Главное — понять логику. Тогда задание № 17 перестанет казаться сложным и превратится в предсказуемую задачу на применение шаблона. Немного практики — и это уже лёгкие баллы на экзамене.
Сохрани шаблон, прорешай несколько вариантов из ФИПИ — и на экзамене ты точно будешь чувствовать себя уверенно.