Найти в Дзене

Программные методы решения 17 задания ЕГЭ по информатике

Задание 17 ЕГЭ по информатике проверяет умение анализировать и обрабатывать последовательности целых чисел. Это задание мы решаем исключительно с использованием программы на языке Python. В этой статье мы пока не будем разбираться с формулировками 17 заданий и выводить алгоритм решения. Для начала стоит рассмотреть фундаментальные подходы, которые станут основой для решения любых вариантов 17 задания. Мы научимся правильно читать данные из файлов, эффективно обрабатывать списки чисел и применять различные операции к последовательностям. Данные в задании 17 представлены в виде текстового файла, где каждая строка содержит одно целое число. Числа могут быть как положительными, так и отрицательными, что нужно учитывать при написании программы. Наша задача — научиться эффективно извлекать эти данные и работать с ними. В Python существует несколько способов открыть файл и прочитать из него данные, но профессиональные программисты всегда используют менеджер контекста with. Это не просто реком
Оглавление

О задании

Задание 17 ЕГЭ по информатике проверяет умение анализировать и обрабатывать последовательности целых чисел. Это задание мы решаем исключительно с использованием программы на языке Python.

В этой статье мы пока не будем разбираться с формулировками 17 заданий и выводить алгоритм решения. Для начала стоит рассмотреть фундаментальные подходы, которые станут основой для решения любых вариантов 17 задания. Мы научимся правильно читать данные из файлов, эффективно обрабатывать списки чисел и применять различные операции к последовательностям.

Данные в задании 17 представлены в виде текстового файла, где каждая строка содержит одно целое число. Числа могут быть как положительными, так и отрицательными, что нужно учитывать при написании программы. Наша задача — научиться эффективно извлекать эти данные и работать с ними.

Работа с файлами

В Python существует несколько способов открыть файл и прочитать из него данные, но профессиональные программисты всегда используют менеджер контекста with. Это не просто рекомендация — это стандарт, который гарантирует безопасную работу с файлами.

Менеджер контекста автоматически закрывает файл после завершения работы с ним, даже если в процессе выполнения кода произойдет ошибка. Это освобождает ресурсы операционной системы и предотвращает потенциальные проблемы.

В рамках небольшой программы для решения одного задания ЕГЭ игнорирование подхода с использованием менеджера контекста, конечно, не вызовет никаких проблем. Но всё же, если вы решили связать свою жизнь с программированием, то стоит сразу писать код в соответствии с принятыми нормами.

Для чтения данных с файла нам необходимо написать конструкцию менеджера контекста with … as, внутри которой следует разместить функцию open(). Предположим, что нам нужно считать данные с файла «file.txt», тогда в программе это будет выглядеть так:

-2

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

Файловые объекты в Python поддерживают протокол итерации. Это означает, что мы можем напрямую перебирать строки файла в цикле, не используя методы read(), readline() или readlines() (про них была отдельная статья). Это очень удобно для наших целей.

Рассмотрим два популярных способа преобразования строк файла в список целых чисел:

  1. Через списочное включение
  2. Через функцию map()

Первый способ самый простой и интуитивно понятный: перебираем в цикле каждую строку из файла и приводим имеющиеся там значения в целочисленный формат функцией int():

-3

Но мы же будем пользоваться вторым способом:

-4

Здесь функция map() применяет функцию int() к каждой строке файла, а list() преобразует результат в список.

Этот способ с использованием map() работает быстрее, особенно на больших объемах данных. Причина в том, что функция map() реализована на уровне C и оптимизирована для подобных операций. Списочное включение, хотя и читается более наглядно, выполняется чуть медленнее, так как интерпретатор Python должен обрабатывать больше байт-кода.

Для задания 17 ЕГЭ разница в скорости обычно незаметна, поэтому можете использовать любой вариант. Однако знание о преимуществах map() пригодится вам в будущем при работе с действительно большими объёмами данных.

Давайте попробуем прочитать данные из файла «numbers.txt», в котором в каждой строке находится по одному числу: 4, 8, 15, 16, 23, 42.

-5

Работа со списками

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

Базовые функции для работы со списками

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

Давайте с помощью неё выведем максимальное число из нашего файла:

-6

Функция min(), напротив, позволяет вернуть наименьшее число из списка:

-7

Причем обратите внимание, что в эти функции достаточно просто передать сам список! Никаких циклов для перебора каждого значения писать не нужно, всё уже реализовано «под капотом» у этих функций.

Теперь давайте рассмотрим, как найти среднее арифметическое. Конечно, самым простым вариантом здесь является использование функции mean() из встроенного модуля statistics:

-8

Но мы реализуем эту функцию самостоятельно! Для вычисления среднего арифметического нам нужно знать сумму чисел и их количество. А в этом нам помогут еще две функции: sum() и len().

Функция sum() позволяет вернуть сумму всех числовых значений списка:

-9

Получили сумму 108, всё как и должно быть! Теперь подсчитаем количество значений в списке data с помощью функции len():

-10

А для вычисления среднего арифметического мы просто поделим сумму на количество элементов списка:

-11

Перебор пар и троек последовательных элементов

Одна из ключевых особенностей задания 17 — необходимость анализировать не отдельные числа, а их комбинации: пары, тройки или даже четвёрки последовательных элементов. Например, нужно проверить, удовлетворяют ли какому-то условию три идущих подряд числа.

Для списка [1, 2, 3, 4, 5] нам нужно перебрать такие тройки:

  • 1, 2, 3
  • 2, 3, 4
  • 3, 4, 5

Неопытные программисты часто используют цикл с индексами:

-12

Этот код работает, но имеет недостатки: он менее читаем, более подвержен ошибкам (легко ошибиться с индексами) и идеологически неправилен с точки зрения Python. В Python есть правило: если вам нужно работать с самими элементами, а не с их индексами, не используйте индексы!

Функция zip() — используется для параллельного перебора нескольких последовательностей. Она объединяет элементы из нескольких итерируемых объектов в кортежи.

Посмотрим на простой пример работы zip():

-13

Функция zip() берет первые элементы из каждого списка и формирует кортеж (1, ‘a’), затем вторые элементы — кортеж (2, ‘b’) и так далее.

Теперь применим эту логику для перебора троек. Если мы передадим в zip():

  • весь список целиком (1, 2, 3, 4, 5)
  • список без первого элемента (nums[1:] — (2, 3, 4, 5)
  • список без первых двух элементов (nums[2:] — 3, 4, 5)

То на каждой итерации цикла получим по три последовательных элемента:

-14

Давайте разберём, как это работает:

Первая итерация:

  • nums начинается с 1
  • nums[1:] начинается с 2
  • nums[2:] начинается с 3
  • Получаем кортеж (1, 2, 3)

Вторая итерация:

  • Берём следующие элементы: (2, 3, 4)

Третья итерация:

  • Берём следующие элементы: (3, 4, 5)

Функция zip() завершает работу, когда заканчивается самая короткая последовательность. В нашем случае nums[2:] содержит только 3 элемента [3, 4, 5], поэтому цикл выполнится ровно 3 раза.

Аналогично для пар элементов можно использовать такую запись:

-15

Этот подход с zip() является стандартным в Python, и именно его мы будем использовать при решении задания 17.

Ну и давайте для примера проверим на практике работу всех описанных ранее функций и методов. Пусть у нас есть файл «file.txt» с таким содержимым: «5, 17, 53, 8, 46, 14, 23, 10». Давайте определим количество пар чисел, в которых сумма элементов пары больше максимального элемента всей последовательности чисел. В ответ выведем количество таких пар и минимальную сумму этих пар.

Для начала мы считаем данные с предложенного файла и сохраним их в виде списка data:

-16

Теперь с помощью функции max() найдём максимальный элемент последовательности:

-17

Далее создадим список ans, в который будем сохранять сумму подходящих под условие пар:

-18

В цикле будем перебирать каждую пару и проверять, что их сумма больше элемента, хранящегося в переменной max_el:

-19

Если условие выполняется, помещаем сумму обоих элементов пары в список ans с помощью метода append:

-20

Осталось лишь вывести количество найденных пар с помощью функции len() и минимальную сумму этих пар с помощью min():

-21

Запускаем нашу программу и видим на экране числа 4 и 54. Таким образом, мы нашли 4 подходящие под условие пары, а минимальная сумма такой пары чисел равняется 54.

Можно сказать, что это такая упрощенная версия задачи, которую мы будем решать в 17 заданиях. Но основательным разбором алгоритма решения этих заданий мы займёмся уже в следующей статье.