
Системы счисления. Кодирование чисел
Штана Альберт Игоревич
В этой статье будет разобрано задание 14.
Рассмотрим типовые задачи из четырнадцатого задания ЕГЭ по информатике.
Данное задание относится к повышенному уровню сложности.
Время выполнения задания ≈ 3 минуты.
Для того чтобы решать задания № 14 ЕГЭ — нужно знать теорию по системам счисления, переводы чисел, а также двоичную арифметику. Информация по системам счисления описана в статье в статье(ссылка ниже):
Ссылка на статью: Системы счисления.
Сколько единиц и сколько значащих нулей содержится в значении выражения:
Упростим решение, чтобы не выделять в исходном выражении какие-либо пары слагаемых, а оперировать только со значениями их показателей степеней и знаками сложения/вычитания.
| Слагаемые | Степени и знаки | Добавляется единиц |
|---|---|---|
| Степень = 12, знак "+" | 1 | |
| Степень = 10, знак "+" | 1 | |
| Степень = 8, знак "-" | (10-8)-1=1 | |
| Степень = 6, знак "-" | (8-6)-1=1 | |
| + 6 | Знак "+" | 2 |
Ответ: 6 единиц, 7 нулей.
Сколько единиц и сколько значащих нулей содержится в двоичной записи числа:
| Слагаемые | Степени и знаки | Добавляется единиц | Единиц в числе |
|---|---|---|---|
| Степень = 4023, знак "+" | 1 | 1 | |
| Степень = 2684, знак "-" | (4023-2684)-1=1338 | 1338 | |
| Степень = 1343, знак "+" | 1 | 1339 | |
| Степень = 10, знак "-" | (1343-10)-1=1332 | 2671 | |
| Степень = 8, знак "-" | (10-8)-1=1 | 2672 | |
| Степень = 6, знак "-" | (8-6)-1=1 | 2673 |
Получается, что в заданном числе 2673 единицы в двоичном представлении.
Ответ: 2673 единицы, 1353 нуля.
Сколько единиц в двоичной записи числа:
| Слагаемые | Степени и знаки | Добавление единиц |
|---|---|---|
| Степень = 3000, знак "+" | 1 | |
| Степень = 1000, знак "+" | 1 | |
| Степень = 250, знак "-" | (1000-250)-1=749 | |
| Знак "+" | 2 |
Ответ: 753.
Сколько значащих нулей в двоичной записи числа:
В двоичной системе количество значащих нулей легко найти как разность общего количества разрядов в числе и количества единиц в нём, поэтому данная задача сводится к подсчёту количества единиц в числе.
| Слагаемые | Степени и знаки | Добавление единиц |
|---|---|---|
| Степень = 1024, знак "+" | 1 | |
| Степень = 768, знак "+" | 1 | |
| Степень = 128, знак "-" | (768-128)-1=639 | |
| Степень = 8, знак "-" | (128-8)-1=119 | |
| Степень = 3, знак "+" | 1 | |
| Степень = 1, знак "+" | 1 | |
| Степень = 0, знак "+" | 1 |
Ответ: 262
Решение подобных задач для других систем счисления в целом аналогично. При этом обычно в условии фигурируют цифры, получаемые вычитанием "из нуля", так что рассмотренные выше принципы решения вполне применимы и в этих случаях.
Значение арифметического выражения
| Слагаемые | Степени и знаки | Добавление единиц |
|---|---|---|
| Степень = 54, знак "+" | 1 единица | |
| Степень = 36, знак "+" | 1 единица(уходит в заём) | |
| Степень = 2, знак "-" | 36-2=34(двойки) |
В задаче нас интересуют только двойки, поэтому количества единиц мы не учитываем, а количество двоек равно 34.
Ответ: 34
Значение арифметического выражения
| Слагаемые | Степени и знаки | Добавление единиц |
|---|---|---|
| Степень = 6051, знак "+" | 1 единица | |
| Степень = 1000, знак "+" | 1 единица(уходит в заём) | |
| Степень = 777, знак "-" | 1000-777=223(шестёрки) | |
| Знак "+" | 1 тройка |
Ответ: 223 шестёрки и 5827 нулей.
Значение выражения
| Слагаемые | Степени и знаки | Добавление единиц |
|---|---|---|
| Степень = 18, знак "+" | 1 единица(уходит в заём) | |
| Степень = 10, знак "-" | 18-10=8 шестёрок | |
| Степень = 777, знак "-" | 1 единица(уходит в заём) | |
| Знак "-" | В разряде 0 - "5" В разряде 1 - "6" |
Особое внимание уделяем вычитанию семеричной двойки в последнем, нулевом разряде: здесь при вычитании(7-2) появляется шестёрка, а из разряда 1 производится заём единицы. Поэтому в разряде 1 имеем 7-1=6 и заём из разряда 2, где бывшая там единица заменяется на нуль, и цепочка заёмов на этом прекращается.
Ответ: 9
Значение выражения
| Слагаемые | Степени и знаки | Добавление единиц |
|---|---|---|
| Степень = 25, знак "+" | 1 единица | |
| Степень = 16, знак "+" | 1 единица(уходит в заём) | |
| Степень = 2, знак "-" | 16-2=14 двоек, одна истрачена на заём — 13 двоек и 1 единица | |
| Степень = 1, знак "-" | 1 двойка, истрачена на заём — получена 1 единица | |
| Знак "-" | 1 единица |
Ответ: 30
Далее используем язык программирования Python для решения подобных и более сложных задач.
Значение выражения:
f = 7 * 6561**46 + 8 * 729**15 - 6 * 5832
c = 0
while f > 0:
if f % 9 == 7:
c += 1
f //= 9
print(c)
В переменную f записываем арифметическое выражение. Две звёздочки подряд обозначают возведение в степень. Заводим переменную c, которая будет отвечать за ответ. Сам перевод числа f в девятеричную систему происходит в цикле WHILE.
Вычисляем остатки от деления на 9. Очередная цифра в 9-ричной системе, это и есть остаток при делении f на 9. Если очередной остаток равен нужной цифре "7", то мы прибавляем счётчик с. Так же производим целочисленное деление на 9, чтобы остатки менялись. Алгоритм точно такой же, как если бы переводили на листке бумаги делением уголком.
Продолжая данный алгоритм, в переменной f будет рано или поздно ноль.
Важно понимать, что в начале у нас идёт последняя цифра в девятеричной системе, при следующем проходе цикла - предпоследняя и т.д.
Ответ: 2
Определите количество цифр с числовым значением, превышающим 9, в 27-ричной записи числа, заданного выражением:
f = 2 * 729**2014 + 2 * 243**2016 - 2 * 81**2018 + 2 * 27**2020 - 2 * 9**2022 - 2024
c = 0
while f > 0:
if f % 27 > 9:
c += 1
f //= 27
print(c)
Решение почти такое же, как в прошлой задаче, но теперь мы подсчитываем только те цифры, которые больше 9.
Ответ: 2687
Значение арифметического выражения
f = 51 * 7**12 - 7**3 - 22
summ = 0
while f > 0:
if f % 7 > 3:
summ += f % 7
f //= 7
print(summ)
Здесь решение похоже на предыдущую задачу. Создаём переменную summ для ответа. Суммируем только те цифры в семеричной системе, которые больше трёх.
Ответ: 65
В выражении
Необходимо перебирать каждую цифру из шестнадцатеричной системы (0-15) с помощью цикла. Нас будут интересовать те значения x, при котором сумма этих чисел делится на 15.
for x in range(0, 16):
a = 13 * 16 ** 0 + 10 * 16 ** 1 + 11 * 16 ** 2 + x * 16 ** 3 + 1 * 16 ** 4
b = 14 * 16 ** 0 + 15 * 16 ** 1 + x * 16 ** 2 + 12 * 16 ** 3 + 2 * 16 ** 4
if (a + b) % 15 == 0:
print(x, (a + b) // 15)
Чтобы проверить, делится ли данное выражение на 15, переводим оба слагаемых в нашу родную десятичную систему. В задаче нужно написать для наименьшего найденного значения x результат от деления данной суммы на 15.
Ответ: 18341
Числа M и N записаны в системах счисления с основаниями 15 и 13 соответственно.
for A in range(1, 2000):
for x in range(0, 13):
for y in range(0, 13):
M = 5 * 15 ** 0 + x * 15 ** 1 + 3 * 15 ** 2 + 2 * 15 ** 3 + y * 15 ** 4 + 2 * 15 ** 5
N = y * 13 ** 0 + 9 * 13 ** 1 + x * 13 ** 2 + 7 * 13 ** 3 + 6 * 13 ** 4
if (M + A) % N == 0:
print(A)
Нужно найти A, значит, начинаем перебирать эту переменную в цикле. Изначально стоит пробовать запускать цикл из небольших верхних пределов значений для range, т.к. нужно найти наименьшее значение. Идём от 1, т.к. речь идёт о натуральных числах. Перебираем x и y. Они могут принимать значения из алфавита в 13-ой системе. Берём наименьшую систему, т.к. эти переменные есть и в первом числе, и во втором числе.
Если выполняется условие задачи, то нам интересно такое A, при котором это произошло.
В этой задаче A получается достаточно большим, поэтому верхний предел цикла по функции range удалось найти уже при значении 2000.
Ответ: 1535
Укажите через запятую в порядке возрастания все десятичные натуральные числа, не превосходящие 17, запись которых в троичной системе счисления оканчивается на две одинаковые цифры.
for i in range(3, 18):
# Последняя цифра в троичной системе
last1 = i % 3
# Предпоследняя цифра в троичной системе
x = i
x //= 3
last2 = x % 3
if last1 == last2:
print(i)
Остаток от деления на 3 - это и есть последняя цифра в троичной системе. Чтобы найти предпоследнюю цифру в троичной системе, нужно выполнить целочисленное деление числа (i) на 3, потом вновь найти остаток от деления.
Используем вспомогательную переменную x, чтобы не изменять значение первоначального числа i. Если выполняется условие задачи, печатаем i, при котором это произошло.
Начинаем перебор цикла с 3, т.к. именно с этого числа представление в троичной системе будет содержать минимум 2 разряда.
Ответ: 4, 8, 9, 13, 17
Чему равно наименьшее основание позиционной системы счисления x, при котором 225x = 405y? Ответ записать в виде целого числа.
for x in range(2, 16):
for y in range(2, 16):
a = 5 * x**0 + 2 * x**1 + 2 * x**2
b = 5 * y**0 + 0 * y**1 + 4 * y**2
if a == b:
print(x)
Перебираем переменные x и y в циклах в примерном диапазоне от двоичной до шестнадцатеричной систем счисления. Внутри вложенных циклов переведём одно и второе число по правилам 8 класса в десятичную систему. Если числа окажутся равны, печатаем такое значение x, при котором это произошло.
Ответ: 8
Запись числа в девятеричной системе счисления заканчивается цифрой 4. Какой будет последняя цифра в записи этого числа в троичной системе счисления?
for i in range(9, 20):
if i % 9 == 4:
print(i, i % 3)
Используем то, что последняя цифра числа в какой-то системе счисления - это и есть остаток от деления этого числа на основание данной системы.
Ответ: 1
Укажите через запятую в порядке возрастания все основания систем счисления, в которых запись числа 23 оканчивается на 2.
Нужно перебрать все числа от 3 до 23 и определить, какие из них при делении числа 23 дадут остаток 2.
for n in range(3, 24):
if 23 % n == 2:
print(n)
Ответ: 3, 7, 21
В какой системе счисления выполняется равенство 12 · 13 = 222? В ответе укажите число – основание системы счисления.
Если бы мы находились в десятичной системе, то последней цифрой была бы 6 (2 * 3). Но у нас 2! Т.е. cистема счисления меньше или равна 6 и больше или равна 4, т.к. если бы система счисления была больше 6, то у нас была бы 6 последняя цифра.
def F(num, n):
s = ''
while num > 0:
s += str(num % n)
num //= n
return s[::-1]
for x in range(4, 6):
a = int("12", x)
b = int("13", x)
n = F(a * b, x)
if n == '222':
print(x)
Шестёрка не "поместилась" в младший разряд, от неё осталось только 2. Остальные 4 единицы ушли в более старший разряд. Если 4 единицы составляют единицу более старшего разряда, то значит, мы находимся в четверичной системе.
Ответ: 4
Запись числа 338 в системе счисления с основанием N содержит 3 цифры и оканчивается на 2. Чему равно максимально возможное основание системы счисления?
def F(num, n):
s = ''
while num > 0:
s += str(num % n)
num //= n
return s[::-1]
for x in range(20, 2, -1):
num = 338
n = F(num, x)
if len(n) == 3 and n[-1] == '2':
print(x, n)
break
В данной задаче можно применить формулу:
338 число будет точно больше, чем двухзначное число с основанием N. Получается неравенство:
Сказано, что число в системе с основанием N оканчивается на 2. Поэтому первый остаток должен быть равен 2!

Будем идти вниз от числа 18 и проверять, на что делится 336.
Число 336 должно делится на N.
Подошло число 16 (16 * 21 = 336!)
Ответ: 16
Значение выражения
Идея алгоритма:
k = 216**5 + 6**3 - 1
flag = False
X = 1
while X < k:
n = 0
k1 = k - X
while k1 > 0:
if k1 % 6 == 5:
n += 1
k1 //= 6
if n == 12:
flag = True
break
X += 1
if flag:
print(X)
Ответ: 259
Значение арифметического выражения
В ответе запишите число в десятичной системе счисления.
Напишем программу на языке Python аналогичную в предыдущей задаче. Заменим выражение, обернув его в цикл for вместо while. Также поменяем условия внутри while при переборе всех разрядов у числа. И наконец, условие выхода из цикла тоже поменяем.
# По условию X не больше 2030. range начинаем с 2030 до 1, т.к. ищем наибольший x.
# третий параметр -1 отвечает за шаг, т.е. мы уменьшаем число в последовательности с 2030
for x in range(2030, 1, -1):
f = 3 ** 100 - x
# Счётчик нулей
k1 = 0
# Перебираем цифры в троичной системе
while f > 0:
if f % 3 == 0:
k1 += 1
f //= 3
if k1 == 5:
print(x)
break
Ответ: 2024
В некоторой системе счисления записи десятичных чисел 66 и 40 заканчиваются на 1. Определите основание системы счисления.
Ещё раз про основания. Нужно найти такое число, чтобы числа 66 и 40 при делении на него давали остаток 1. Первый остаток при делении на основание системы - это и есть последняя цифра числа в этой системе счисления.
Искомое число должно быть делителем чисел 65 (66-1) и 39 (40-1). У числа 39 не так много делителей: 1, 3, 13, 39.
Видим, что число 65 делится на 13 (65 : 13 = 5).
Поэтому искомое число равно 13.
for n in range(2, 40):
if 66 % n == 1 and 40 % n == 1:
print(n)
break
Ответ: 13
Операнды арифметического выражения записаны в системе счисления с основанием 19.
Значение арифметического выражения
В задании сказано, что x - это число в 19-ичной системе. Значит нам нужно перебрать все x от 18 до 0 в цикле и подставить в выражение. Расписав отдельно между операцией + значения чисел в развёрнутой форме в десятичной системе - сохраним результат в переменные значения a и b. Далее условие if проверяет(как по условию), что результат всего выражения(a+b) делится без остатка на 18. Команда print будет выводить все такие варианты и остаётся только выбрать в консоли ответ как наибольшее значение x.
for x in range(18, -1, -1):
a = 1*19**0 + 2*19**1 + x*19**2 + 7*19**3 + 9*19**4 + 8*19**5 + 8*19**6 + 9*19**7
b = 3*19**0 + 2*19**1 + 9*19**2 + x*19**3 + 2*19**4
if (a + b) % 18 == 0:
print(x, (a + b) // 18)
break # т.к. ищем максимальный x и идём в цикле от наибольшего x можно уже прервать цикл
Ответ: 469034148
Второй вариант ИЛИ решить даже легче. В переменную R сначала сохраним результат вычисления данного в задании выражения. Далее переменная k служит счётчиком, отвечающим в конце на вопрос задачи в print. Далее запускаем цикл по условию пока результат выражения больше нуля -> мы будем остаток от деления на 25 и сокращать кол-во разрядов у числа целочисленным делением на 25. Тем самым в условии if мы посчитаем количество значащих нулей в результате выражения, так как, если бы этот результат был записан в 25-ичной системе счисления.
R = 3*3125**8 + 2*625**7 - 4*625**6 + 3*125**5 - 2*25**4 - 2024
k = 0
while R > 0:
if R % 25 == 0:
k += 1
R = R // 25
print(k)
Ответ: 9
1 вариант задания остался прежним как в демоверсии 2024 года.
Изменился совсем незначительно вариант ИЛИ. И добавился ещё второй вариант ИЛИ.
Значение арифметического выражения
Значение арифметического выражения
Приведу ещё одно своё решение этого задания.
В задании сказано, что x - это число в 19-ичной системе. Значит нам нужно перебрать все x от 0 до 18 в цикле и подставить в выражение. Расписав отдельно между операцией + значения чисел в развёрнутой форме в десятичной системе - сохраним результат в переменные значения a и b. Далее условие if проверяет(как по условию), что результат всего выражения(a+b) делится без остатка на 18. Команда results.add будет добавлять все такие варианты в список. В конце остаётся только вывести в консоли ответ, как наибольшее значение(max).
Через "сохранение" всех значений в списке.
results = []
for x in range(0, 19):
a = 9 * 19 ** 7 + 8 * 19 ** 6 + 8 * 19 ** 5 + 9 * 19 ** 4 + 7 * 19 ** 3 + x * 19 ** 2 + 2 * 19 ** 1 + 1 * 19 ** 0
b = 2 * 19 ** 4 + x * 19 ** 3 + 9 * 19 ** 2 + 2 * 19 ** 1 + 3 * 19 ** 0
if (a + b) % 18 == 0:
results.append((a + b) // 18)
print(max(results))
Ответ: 469034148
Второй вариант ИЛИ решить даже легче. В переменную R сначала сохраним результат вычисления данного в задании выражения. Далее переменная k служит счётчиком, отвечающим в конце на вопрос задачи в print. Далее запускаем цикл по условию пока результат выражения больше нуля -> мы будем остаток от деления на 25 и сокращать кол-во разрядов у числа целочисленным делением на 25. Тем самым в условии if мы посчитаем количество значащих нулей в результате выражения, так как, если бы этот результат был записан в 25-ичной системе счисления.
R = 3*3125**8 + 2*625**7 - 4*625**6 + 3*125**5 - 2*25**4 - 2025
counter = 0
while R > 0:
if R % 25 == 0:
counter += 1
R //= 25
print(counter)
Ответ: 10
Также через "сохранение" всех значений в списке.
results = []
for x in range(1, 2031): # x не должен превысить значение 2030
R = 7 ** 170 + 7 ** 100 - x
# Счётчик нулей
counter = 0
# Перебираем цифры все цифры в числе
while R > 0:
if R % 7 == 0: # Условие проверки для 7-ичной системы
counter += 1 # считаем нули
R //= 7 # Уменьшение разряда числа в 7-ичной системе
if counter == 71:
results.append(x) # Добавить в список x удовлетворяющий условию задачи по количеству нулей
print(max(results)) # Выводим ответ как сохранившейся в списке максимальный x
Ответ: 2029
p.s. Вариантов и способов решения этого и подобных заданий № 14 в коде на python всегда может быть несколько: "замудренных", изящных, коротких и не очень.
Значение арифметического выражения
записали в системе счисления с основанием 27. Определите в 27-ричной записи числа количество цифр с числовым значением, превышающим 9.
R = 2 * 2187 ** 2020 + 729 ** 2021 - 2 * 243 ** 2022 + 81 ** 2023 - 2 * 27 ** 2024 - 6561
counter = 0
while R > 0:
if R % 27 > 9:
counter += 1
R //= 27
print(counter)
Ответ: 3367
Операнды арифметического выражения записаны в системе счисления с основанием 29.
В записи чисел переменной x обозначена неизвестная цифра из алфавита 29-ричной системы счисления. Определите наибольшее значение x, при котором значение данного арифметического выражения кратно 28. Для найденного x вычислите частное от деления значения арифметического выражения на 28 и укажите его в ответе в десятичной системе счисления. Основание системы счисления указывать не нужно.
for x in range(28, -1, -1):
a = 4 * 29 ** 0 + 7 * 29 ** 1 + 8 * 29 ** 2 + x * 29 ** 3 + 3 * 29 ** 4 + 2 * 29 ** 5 + 9 * 29 ** 6
b = 2 * 29 ** 0 + 5 * 29 ** 1 + 1 * 29 ** 2 + 6 * 29 ** 3 + x * 29 ** 4 + 4 * 29 ** 5 + 2 * 29 ** 6 + 5 * 29 ** 7
if (a + b) % 28 == 0:
print(x, (a + b) // 28)
break # т.к. ищем максимальный x и идём в цикле от наибольшего x можно уже прервать цикл
Ответ: 3319197720
Значение арифметического выражения
В ответе запишите число в десятичной системе счисления.
results = []
for x in range(1, 3001): # x не должен превысить значение 3000
R = 9 * 11 ** 210 + 8 * 11 ** 150 - x
# Счётчик нулей
counter = 0
# Перебираем цифры все цифры в числе
while R > 0:
if R % 11 == 0: # Условие проверки для 11-ичной системы
counter += 1 # считаем нули
R //= 11 # Уменьшение разряда числа в 7-ичной системе
if counter == 60: # насчитали ровно 60 нулей
results.append(x) # Добавить в список x удовлетворяющий условию задачи по количеству нулей
print(max(results)) # Выводим ответ как сохранившейся в списке максимальный x
Ответ: 2992
Попробуйте сами запустить код в окне ниже с интерпретатором Python и повторите примеры из статьи чтобы самим увидеть и понять как всё это работает. Для этого в ячейке с кодом нажмите клавиши на клавиатуре Shift+Enter или запустите код через кнопку Run по значку ▶.