Программное решение задания № 5 на языке Python

Автор статьи: Андрей Рогов

О чём задание № 5

Пятое задание ЕГЭ по информатике посвящено числовым алгоритмам. Оно считается базовым по сложности. Обычно задание связано с переводом числа из десятичной системы счисления в другую, его модификацией и переводом обратно. Вопросы могут касаться поиска максимального, минимального результата алгоритма или определения исходного числа, которое приводит к заданному результату. Специальное программное обеспечение для того, чтобы решить задачу, не требуется. В статье по ссылке рассмотрен аналитический подход к заданию, а здесь поговорим о решении с помощью кода на Python.

Основная идея

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

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

Навыки программирования

В статье об аналитическом способе решения описывались встроенные методы перевода чисел в двоичную, восьмеричную, шестнадцатеричную систему счисления и обратно в десятичную.

Напомним, как они выглядят на языке Python:

# Перевод в двоичную
b = bin(x)[2:]
b = f'{x:b}'
b = format(x, 'b')
# Перевод в восьмеричную
b = oct(x)[2:]
b = f'{x:o}'
b = format(x, 'o')
# Перевод в шестнадцатеричную
b = hex(x)[2:]
b = f'{x:x}'
b = format(x, 'x')

# Перевод в десятичную
a = int(x, b)
# где b — основание системы счисления (от 2 до 36), в которой записано число x (в виде строки)

Для перевода чисел в произвольную систему счисления рекомендуем использовать собственную функцию. Вот две её реализации: с хранением результата в виде списка и в виде строки:

def to_base(x, b):
s = []
while x > 0:
    s.append(x % b)
    x //= b
s.reverse()
return s
def to_base(x, b):
s = ''
while x > 0:
    s = str(x % b) + s
    x //= b
return s

Функция, которая возвращает результат в виде списка, будет корректно работать со всеми основаниями систем счисления (но вместо буквенных цифр будут числа). Функция со строками будет корректно работать только с основаниями до 10. В этом задании встречались двоичная и троичная системы счисления, поэтому можно использовать обе функции. Вариант с str удобнее, поскольку функция int работает со строками, bin возвращает строку и преобразования чисел удобнее делать через строки. Далее будем использовать именно этот вариант.

Следующий важный навык — работа со строками. Чтобы решить задание № 5, нужно уметь дописывать числа в начало или в конец строки. Помните, что строки в Python — неизменяемые объекты, поэтому в каждом случае нужно будет создавать новые. Необходимо также знать, как работают срезы.

Приведём несколько примеров:

s = '012345'
# строка со второго символа
s[1:]
'12345'
# строка с третьего символа
s[2:]
'2345'
# строка без последнего символа
s[:-1]
'01234'
# строка без двух последних символов
s[:-2]
'0123'

Рассмотрим несколько вариантов решения заданий.

Задача 1. Программное решение с помощью Python

Ссылка на задачу

img

На примере этого задания разберём общий подход. Для начала нужно организовать перебор всех возможных значений N. Нижняя граница понятна: числа натуральные, поэтому минимальное число — 1. Как быть с верхней? Актуальные типы заданий содержат примеры результатов для некоторых исходных чисел. На первом этапе решения можно ограничиться числами, которые есть в примерах, чтобы проверить на них корректность работы алгоритма.

for n in range(1, 13):

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

b = bin(n)[2:]

На втором шаге нужно проверить исходное число на чётность и дописать необходимые цифры.

if n % 2 == 0:  # если число чётное
          b = b + '01'  # приписать справа
     else:
          b = '1' + b + '1'  # приписать слева и справа

Последний шаг — перевести число в десятичную систему счисления. На этом этапе решения будем выводить все начальные и конечные значения на экран. Полный код программы:

for n in range(1, 13):
     b = bin(n)[2:]  # двоичная запись числа
     if n % 2 == 0:  # если число чётное
          b = b + '01'  # приписать справа
     else:
          b = '1' + b + '1'  # приписать слева и справа
     r = int(b, 2)  # перевод в десятичную систему счисления
     print(n, r)

Вывод программы:

1 7
2 9
3 15
4 17
5 27
6 25
7 31
8 33
9 51
10 41
11 55
12 49

Сверимся с условием задачи. Для числа 5 наша программа вывела 27, для числа 12 — 49, что соответствует условию. Рекомендуем всегда проверять корректность работы алгоритма перед тем, как выполнять задание.
Теперь можем переходить к вопросу задачи. Требуется найти минимальное число N, дающее в результате R больше 156.

Один из самых простых способов получить ответ — расширить границы цикла и просмотреть вывод программы. Это не очень удобно, к тому же есть вероятность ошибиться.

Чтобы видеть в выводе только подходящие результаты, можно его фильтровать:

for n in range(1, 100):
     b = bin(n)[2:]  # двоичная запись числа
     if n % 2 == 0:  # если число чётное
          b = b + '01'  # приписать справа
     else:
          b = '1' + b + '1'  # приписать слева и справа
     r = int(b, 2)  # перевод в десятичную систему счисления
     if r > 156:  # фильтр
          print(n, r)

Мы расширили границы цикла (теперь он выполняется от 1 до 99) и выводим на экран информацию, только если R больше 156. Первое значение, которое мы увидим на экране, будет подходящим. Также для удобства можно прекратить выполнение цикла после того, как будет найден первый результат, с помощью команды break. Но это будет корректно, только если вопрос задания о наименьшем N.

Задача 2. Программное решение с помощью Python

Ссылка на задачу

img

Видим, что строится троичная запись. Будем использовать функцию для перевода в троичную систему счисления:

def to_base(x, b):
     s = ''
     while x > 0:
          s = str(x % b) + s
          x //= b
     return s


for n in range(1, 13):
     b = to_base(n, 3)  # троичная запись числа
     if n % 3 == 0:  # если число делится на 3
          b = b + b[-2:]  # приписать справа
     else:
          b = b + to_base(n % 3 * 5, 3)
     r = int(b, 3)
     print(n, r)

Как и в прошлый раз, сначала проанализируем вывод программы и сравним его с условием задачи. Далее перейдём к поиску R. Действия, выполняемые в зависимости от условия, не равноценны. Они по-разному меняют число, давая нелинейную зависимость. Это хорошо видно по выводу программы:

1 14
2 64
3 30
4 41
5 145
6 60
7 68
8 226
9 81
10 95
11 307
12 111

Первое R больше 133, это 145, но оно может быть не минимальным. Нам нужно получить гарантированно правильный ответ. Для этого организуем фильтрацию вывода с двух сторон: ограничим и верхнее, и нижнее значение. Нам требуется R больше 133, мы видим в выводе 145. Попробуем определить, появятся ли другие значения больше 133, но меньше 145. Не забудем увеличить границу цикла:

def to_base(x, b):
     s = ''
     while x > 0:
          s = str(x % b) + s
          x //= b
     return s


for n in range(1, 100):
     b = to_base(n, 3)  # троичная запись числа
     if n % 3 == 0:  # если число делится на 3
          b = b + b[-2:]  # приписать справа
     else:
          b = b + to_base(n % 3 * 5, 3)
     r = int(b, 3)
     if r > 133 and r < 145:  # фильтр
          print(n, r)

Программа выдаст ещё одно число:

15 141

Следовательно, наименьшим числом больше 133 будет 141.

В рассмотренных заданиях было достаточно перебрать числа от 1 до 100. Диапазон мы выбрали исходя из того, какие результаты дают эти числа. Однако в других заданиях такого диапазона может быть недостаточно, а слишком большой перебор может занять много времени.

Внимательно выбирайте диапазон перебора. Некоторые варианты задач ограничивают минимальное или максимальное значение N. Вот пример такого задания:

img

Другие задания

Рассмотренные задачи не исчерпывают всего многообразия задания № 5. Например, в демоверсии ЕГЭ за 2017 год оно выглядело так (тогда его номер был шестым):

img

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

Заключение

Задание № 5 часто можно решить шаблонным кодом. Увы, в стрессовой обстановке экзамена даже элементарные знания, которые всегда выручали, могут забыться. Мы рекомендуем не заучивать код, а научиться использовать его в своих целях. Навыки его написания должны быть первичны, и, обладая ими, можно приступать к такому типу решения. Без крепкой базы программирования это задание нужно научиться решать аналитически.

При подготовке к ЕГЭ рекомендуем использовать несколько способов решения для каждого задания.

Для закрепления материала рекомендуем последовательно решить три подборки задач:

Источник: Яндекс Учебник — Программное решение задания № 5 на языке Python. Каталог разборов: education.yandex.ru.

Назад к статьям Поделиться