
Анализ и построение алгоритмов для исполнителей
Штана Альберт Игоревич
В этой статье будет разобрано задание 5.
Рассмотрим типовые задачи из пятого задания ЕГЭ по информатике.
Данное задание относится к базовому уровню сложности.
Время выполнения задания ≈ 4 минуты.
На вход алгоритма подаётся натуральное число N. Алгоритм строит по нему новое число R по следующему принципу.
Полученная таким образом запись (в ней на два разряда больше, чем в записи исходного числа N) является двоичной записью искомого числа R.
Укажите минимальное число R, которое превышает 42 и может являться результатом работы алгоритма. В ответе это число запишите в десятичной системе.
for n in range(1, 1000):
s = format(n, 'b')
s += str(s.count('1') % 2)
s += str(s.count('1') % 2)
r = int(s, 2)
if r > 42:
print(r)
break
Программа будет выводить различные числа, но нас интересует самое маленькое. В ответе получается 46. Чтобы остановить поток чисел, в условии пишем break.
В программе перебираем натуральные числа от 1 до 1000 с помощью цикла for. Каждое число подставляем в описанный алгоритм, в надежде получить в результате число r, удовлетворяющие условию задачи.
С помощью функции format переводим число n в двоичный вид. Получаем результат в виде строки s.
Чтобы найти сумму цифр получившейся двоичной записи, достаточно подсчитать количество единиц в строке s. Ведь только единицы в двоичной записи дают в сумму результат. Это можно сделать, применив функцию .count() к строке s.
Добавляем справа к строке s остаток от деления суммы цифр на 2. Остаток нужно превратить в строковый тип данных, чтобы "присоединить" его к строке s справа.
Повторяем пункт Б, скопировав строку с пунктом А.
Чтобы обратно превратить строку двоичной записи в десятичное число, используем функцию int(), указав параметр 2.
В конце программы пропишем условие. Если r больше 42, то будем печатать значение r.
Ответ: 46
На вход алгоритма подаётся натуральное число N. Алгоритм строит по нему новое число следующим образом.
Полученная таким образом запись (в ней на два разряда больше, чем в записи исходного числа N) является двоичной записью числа - результата работы данного алгоритма.
Укажите минимальное число N, для которого результат работы алгоритма будет больше 130. В ответе это число запишите в десятичной системе счисления.
for n in range(1, 1000):
s = format(n, 'b')
if n % 2 == 0:
s += '00'
else:
s += '11'
r = int(s, 2)
if r > 130:
print(n)
break
Минимальное число n получается 33.
Обратите внимание, что здесь уже анализируем число n. Если оно чётное, то к переменной s справа дописываем '00', иначе '11'. Так же в этой задаче мы печатаем в ответе само число n.
Ответ: 33
На вход алгоритма подаётся натуральное число N. Алгоритм строит по нему новое число R следующим образом.
Например, двоичная запись 1010 числа 10 будет преобразована в 10011001. Полученная таким образом запись (в ней в два раза больше разрядов, чем в записи исходного числа N) является двоичной записью искомого числа R.
Укажите максимальное нечётное число R, меньшее 256, которое может являться результатом работы данного алгоритма. В ответе это число запишите в десятичной системе.
for n in range(1, 1000):
s = format(n, 'b')
s = s.replace('0', '*')
s = s.replace('1', '10')
s = s.replace('*', '01')
r = int(s, 2)
if r % 2 != 0 and r < 256:
print(r)
Получается наибольшее число 169.
Опять с помощью функции format() переводим число n в двоичный вид. С помощью функции replace() заменяем во всей строке s ноль на звёздочку. Таким образом, мы как бы спрятали первоначальные нули. Затем заменяем "1" на "10", и "*" на "01". В результате мы добьёмся нужных замен, о которых говорится в условии задачи.
Далее, делаем, как в прошлой задаче, только убираем в конце break т.к. ищем максимум, а не минимум.
Ответ: 169
На вход алгоритма подаётся натуральное число N. Алгоритм строит по нему новое число R следующим образом.
Полученная таким образом запись является двоичной записью числа R.
Укажите наибольшее число N, для которого результат работы данного алгоритма меньше 47. В ответе число N укажите в десятичной системе.
for i in range(1, 1000):
n = i
n = n - n % 4 # Выполняем первый пункт
s = format(n, 'b')
s += str(s.count('1') % 2) # Подпункт a) третьего пункта
s += str(s.count('1') % 2) # Подпункт б) третьего пункта
r = int(s, 2)
if r < 47:
print(i)
Перебираем числа от 1 до 1000 с помощью цикла for.
В переменную n по очереди подставляются числа из нашего диапазона (1 до 1000). Чтобы в ответе была возможность написать первоначальное число, заводим ещё одну переменную n, с которой производим основные действия.
Ответ: 11
На вход алгоритма подаётся натуральное число N. Алгоритм строит по нему новое число R следующим образом.
Полученная таким образом запись является двоичной записью искомого числа R.
Например, для исходного числа 6 = 110 результатом является число 1000 = 8, а для исходного числа 4 = 100 результатом является число 1101 = 13.
Укажите минимальное число N, после обработки которого с помощью этого алгоритма получается число R, большее 40. В ответе запишите это число в десятичной системе счисления.
for n in range(1, 1000):
s = format(n, 'b')
if s.count('1') % 2 == 0:
s += '0'
s = '10' + s[2:]
else:
s += '1'
s = '11' + s[2:]
r = int(s, 2)
if r > 40:
print(n)
break
Здесь пишем программу, как в предыдущих примерах. Но, действительно, встречается и новый приём. Нужно изменить левые символы нашей строки s. Это можно сделать с помощью такой конструкции s2:. Таким образом, мы берём всю строку, кроме двух первых символов. Например, s='football', то s2: будет обозначать 'otball'.
Перебираем числа от 1 до 1000 с помощью цикла for. В этом диапазоне надеемся найти наш ответ. С помощью команды format() превращаем число в строку уже в двоичной системе. Сумма цифр в строке зависит только от количества единиц. Нули ничего не дают в сумму. Поэтому применяем функцию .count. Дальше всё делаем, как написано в условии задачи. Команда int(s, 2) переводит строку из двоичной системы в десятичное число.
Ответ: 16
Автомат обрабатывает натуральное число N > 1 по следующему алгоритму:
Пример. Дано число N = 11. Алгоритм работает следующим образом.
При каком наименьшем числе N в результате работы алгоритма получится R > 170? В ответе запишите это число в десятичной системе счисления.
for n in range(2, 1000):
s = format(n, 'b')
s += s[-2]
s += s[1]
r = int(s, 2)
if r > 170:
print(n)
break
Получается наименьшее число 43. К последнему символу можем обратиться как s-1. К предпоследнему как s-2. Но счёт слева начинается с нулевого индекса. Первый символ - это s0, второй символ - это s1 и т.д.
Обратите внимание, что перебирать числа n в этой задаче начинаем с 2. Это делается, чтобы в двоичной системе число имело минимум два разряда. Если начнём с 1, то программа не сможет обратиться к предпоследнему символу и выдаст ошибку!
Ответ: 43
Автомат обрабатывает натуральное число N (1≤N≤255) по следующему алгоритму:
Каково наибольшее число, меньшее 100, которое после обработки автоматом не изменится?
for n in range(1, 256):
s = format(n, 'b')
# делаем 8-ое число
while (len(s) < 8):
s = '0' + s
s = s[:-1] # удаляется последняя цифра
s = s[::-1] # число переворачивается
r = int(s, 2)
if 100 > n == r:
print(n)
Ответ получается 90.
8-битное число имеет длину 8 символов. После того как перевели число n в двоичный вид, с помощью цикла while дописываем нули слева к строке s, пока длина этой строки меньше 8.
Удалить последнюю цифру можно с помощью конструкции s:-1. Здесь мы оставляем все цифры, начиная с первой до последней (не включительно).
Перевернуть строку можно с помощью конструкции s::-1.
Далее решаем как обычно.
Если при перевороте строки получаются незначащие нули, то в этом ничего страшного нет. Функция int() их просто отбрасывает.
Число не изменится, если входное число n равно выходному числу r.
Ответ: 90
На вход алгоритма подаётся натуральное число N. Алгоритм строит по нему новое число R следующим образом.
Полученная таким образом запись является двоичной записью искомого числа R. Например, для исходного числа 6 = 110 результатом является число 100 = 4, а для исходного числа 4 = 100 результатом является число 1101 = 13.
Укажите число N, после обработки которого с помощью этого алгоритма получается наименьшее значение R, большее 49. В ответе запишите это число в десятичной системе.
maxi = 10 ** 9
answer = 0
for n in range(1, 1000):
s = format(n, 'b')
if s.count('1') % 2 == 0:
s += '0'
s = '1' + s[2:]
else:
s += '1'
s = '11' + s[2:]
r = int(s, 2)
if r > 49:
if r < maxi:
maxi = r
answer = n
print(answer)
Здесь алгоритм находит минимальное число r автоматически и для него запоминается значение n, которое пойдет в ответ. Этот приём условно можно назвать "царь горы".
Ответ: 57
На вход алгоритма подаётся натуральное число N. Алгоритм строит по нему новое число R следующим образом.
Например, для исходного числа 11 = 102 результатом является число 102101 = 307, а для исходного числа 12 = 110 это число 11010 = 111.
Укажите минимальное число R, большее 133, которое может быть получено с помощью описанного алгоритма. В ответе запишите это число в десятичной системе счисления.
# Функция получает число, переводит его в троичную систему, возвращает результат в виде строки.
def F(n):
s = ''
while n > 0:
s += str(n % 3)
n //= 3
return s[::-1]
maxi = 10 ** 9
for n in range(1, 1000):
s = F(n)
if n % 3 == 0:
s += s[-2] + s[-1]
if n % 3 != 0:
s += F((n % 3) * 5)
r = int(s, 3)
if r > 133:
maxi = min(maxi, r)
print(maxi)
Здесь вместо функции format нам придётся создать собственную функцию F. Эта функция должна перевести число n в троичную систему и вернуть результат в виде строки.
Рассмотрим эту функцию более подробно. Аналогично переводили из десятичной системы в любую другую в 8 классе делением уголком. Заводим строку s. Пока в переменной n что-то есть, продолжаем переводить в троичную систему. Остаток от деления на 3 - это и есть очередная цифра нашего числа в троичной системе, начиная с конца. Но нужно ещё так же делить целочисленным образом число n на 3. В 8 классе, когда мы переводили уголком, так же делили наше число, и оно становилось всё меньше и меньше. После окончания работы цикла while, в строке s будет нужное нам число в троичной системе, но записанное слева направо. Нужно перевернуть эту строку s::-1, перед тем, как функция вернёт её.
Подобная функция хорошо работает, когда основание системы, куда мы переводим, меньше 10. В противном случае у нас может получиться, к примеру, остаток 11, и трудно будет отличить, где число 11, а где просто две единицы. В этом случае можно попробовать дописать в функцию дополнительные условия.
Далее действуем, как в предыдущих задачах. Так же используем приём "царь горы", т.к. числа r получаются неравномерными.
Ответ: 141
На вход алгоритма подаётся натуральное число N. Алгоритм строит по нему новое число R следующим образом.
Полученное число переводится в десятичную запись и выводится на экран.
Какое наименьшее число, превышающее 40, может получиться в результате работы автомата?
def F(n):
s = ''
while n > 0:
s += str(n % 4)
n //= 4
return s[::-1]
maxi = 10 ** 9
for n in range(1, 1000):
s = F(n)
if len(s) % 2 == 0:
s = s[:len(s) // 2] + '0' + s[len(s) // 2:]
else:
s += '1'
r = int(s, 4)
if r > 40:
maxi = min(maxi, r)
print(maxi)
Проверить количество символов в строке s можно с помощью функции len(). Так s
Далее решаем, как в прошлых задачах.
Ответ: 48
Автомат получает на вход четырёхзначное число. По этому числу строится новое число по следующим правилам:
Пример. Исходное число: 2465. Суммы: 2 * 4 = 8; 6 * 5 = 30. Результат: 308.
Укажите наибольшее число, в результате обработки которого автомат выдаст число 124.
В подобных задачах из ЕГЭ по информатике нумерация происходит начиная со старшего разряда.

Первое правило можно представить следующим образом:

Второе правило заключается в том, что мы "соединяем" два числа, полученных в первом пункте, причём сначала идёт большее число, а затем меньшее.
Проанализируем число 124.

Чтобы четырёхзначное число было наибольшим, выгодно, чтобы в старшем разряде стояла 9. Но, не у числа 12, не у числа 4, нет такого делителя. Какой наибольший делитель мы можем получить? Это число 6. Число 6 является делителем 12-ти. Значит, первая цифра будет 6, а вторая цифра будет 2 (6 * 2 = 12).
Рассмотрим второе число 4. Третий разряд тоже желательно сделать побольше. Значит, в четвёртый разряд поставим 4, а в младший разряд 1 (4 * 1 = 4).
for n in range(1000, 10000):
s = str(n)
x = int(s[0]) * int(s[1])
y = int(s[2]) * int(s[3])
if x > y:
r = str(x) + str(y)
else:
r = str(y) + str(x)
if r == '124':
print(n)
В начале переводим число n в строку. Разбиваем число по цифрам и получаем нужных два числа.
Соединяем эти два числа в порядке убывания. Удобно соединить, превратив опять эти два числа в строчный тип данных.
Проверяем результат под ответ. Важно не забыть, что переменная r в этом решении имеет строчный тип данных.
Ответ: 6241
На вход алгоритма подаётся натуральное число N. Алгоритм строит по нему новое число R следующим образом.
Например, для исходного числа 12 = 1100 результатом является число 1100100 = 100, а для исходного числа 4 = 100 это число 10011 = 19. Укажите минимальное число R, большее 151, которое может быть получено с помощью описанного алгоритма. В ответе запишите это число в десятичной системе счисления.
min_int = 10**10 # Запишем в переменную какое-то большое число
for N in range(1, 1000): # Циклом перебираем все числа для нашего алгоритма
byn_N = format(N, 'b') # переводим число N в двоичный формат
if N % 3 == 0: # Если N делится на 3
byn_N = byn_N + byn_N[len(byn_N) - 3:] # По условию добавляем последние 3 двоичные цифры к записи
# можно так byn_N = byn_N + byn_N[-3] + byn_N[-2] + byn_N[-1] переписать строку выше
else: # иначе по условию пишем код ниже, если не делится на 3 число N
byn_N = byn_N + format((N % 3) * 3, 'b')
# Вычисляем результат
result = int(byn_N, 2) # второй параметр указывает что передается число в двоичной системе
if result > 151: # Если результат больше чем 151 по условию алгоритма, то
min_int = min(result, min_int) # то вычисляем минимум
# print(min_int) # можно здесь увидеть во время перебора какие были минимумы
# print(N) # и какое было исходное число N в шаге с вычислением минимума
print(min_int) # Выводим ответ
Ответ: 163
На вход алгоритма подаётся натуральное число N. Алгоритм строит по нему новое число R следующим образом.
Например, для исходного числа 4 = 100 результатом является число 20 = 10100, а для исходного числа 5 = 101 это число 53 = 110101.
Укажите максимальное число R, которое может быть результатом работы данного алгоритма, при условии, что N не больше 12. В ответе запишите это число в десятичной системе счисления.
Answer = -10**10
for N in range(1, 13): # при условии, что N не больше 12
bN = format(N, 'b') # 1 Строится двоичная запись числа N
if N % 2 == 0: # 2 если N чётное
bN = '10' + bN # 2а к двоичной записи числа слева дописывается 10
else: # 2б если число нечётное
bN = '1' + bN + '01' # к двоичной записи числа слева дописывается 1 и справа дописывается 01
R = int(bN, 2) # перевод в десятичную систему счисления
Answer = max(Answer, R) # Максимальное число R, которое может быть результатом работы данного алгоритма
print(Answer) # 109
Ответ: 109

def F(n):
s = ''
while n > 0:
s += str(n % 3)
n //= 3
return s[::-1]
mini = 10**9 # Условно большое число т.к. требуется найти минимум
num = 10000 # Число по условию больше которого нужно искать минимум
for n in range(1, 100000):
# 1
s = F(n)
# 2
s = list(s)
for i in range(len(s)):
if s[i] == '0':
s[i] = '1'
continue
if s[i] == '1':
s[i] = '2'
continue
if s[i] == '2':
s[i] = '0'
continue
s = ''.join(s) # Далее список обратно в строку
# 3
for c in s:
if c == '0':
s = s[1:]
else:
break
# 4
s = s[::-1]
# 5
summ = 0 # вначале в переменную вычислим сумму
for c in s:
summ += int(c)
# переведём сумму цифр в троичную систему и присоединим в конец к основной строке(из пункта 4)
s += F(summ)
# 6
n = 0
if s != '': # В некоторых случаях весь алгоритм выше может выдавать пустую строку
n = int(s, 3) # Преобразовываем строку(запись в троичной системе) — в десятичную
if n > num: # Если число больше 10000
mini = min(mini, n) # Вычисляем минимум между последним сохранённым результатом
print(mini) # Выводим ответ после того как алгоритм перебрал все числа в цикле
Сначала пишем функцию, которая получает число, переводит его в троичную систему, возвращает результат в виде строки. Далее заводим две переменные: минимум(она же будет результатом задачи) и для сравнения на больше(по условию 10000). Затем напишем цикл: перебираем числа(чем больше тем лучше) для алгоритма исполнителя. И наконец по пунктам решаем задачу:
В конце решения остаётся только проверить число(по условию оно должно быть больше 10000) с переменной созданной в самом начале. Вычислить минимум, и наконец когда перебор завершиться вывести полученный минимум как ответ на задание.
Ответ: 10006
На вход алгоритма подаётся натуральное число N. Алгоритм строит по нему новое число R следующим образом.
Например, для исходного числа 12 = 1100 результатом является число 1100100 = 100, а для исходного числа 4 = 100 это число 10011 = 19.
Укажите минимальное число N, после обработки которого с помощью этого алгоритма получается число R, не меньшее 200.
for N in range(1, 100): # Ищем минимальное число N
bN = format(N, 'b') # 1 Строится двоичная запись числа N
if N % 3 == 0: # Если число N делится на 3
bN = bN + bN[-3:] # то к этой записи дописываются её три последние двоичные цифры
else: # если число N на 3 не делится
ost = (N % 3) * 3 # то остаток от деления умножается на 3,
oB = format(ost, 'b') # переводится в двоичную запись
bN = bN + oB # и дописывается в конец числа
R = int(bN, 2) # перевод в десятичную систему счисления
if R >= 200: # с помощью этого алгоритма получается число R, не меньшее 200
print(N) # Укажите минимальное число N - ответ на задачу
break # т.к. идём в цикле с 1 то минимум будет сразу найден и можно прервать цикл
Ответ: 26
Попробуйте сами запустить код в окне ниже с интерпретатором Python и повторите примеры из статьи чтобы самим увидеть и понять как всё это работает. Для этого в ячейке с кодом нажмите клавиши на клавиатуре Shift+Enter или запустите код через кнопку Run по значку ▶.