Курс№14. Системы счисления0%
Теория · номер 14 из 27

Системы счисления

Числа тут огромные, руками их не посчитать. Зато Python считает их точно, поэтому номер сводится к двум приёмам: читать запись через int и разбирать число на цифры остатками.

7 разделов~35 минут1 первичный балл
  1. 1Что проверяет номер
  2. 2База: int, printable и остатки
  3. 3Считаем цифры в записи
  4. 4Неизвестная цифра x
  5. 5Неизвестное основание и основание больше 36
  6. 6Перебор x: ровно N нулей
  7. 7Ловушки и домашка
Раздел 1 из 7

Что проверяет номер

Есть число или выражение в системе с основанием, отличным от 10. Задачи бывают двух видов.

Считаем цифры

Выражение записали в какой-то системе. Спрашивают, сколько в записи цифр определённого вида.

Значение 5·27²⁰ + 3·9³⁰ − 2 записали в системе с основанием 27. Сколько цифр больше 9?

Ищем неизвестное

В записи чисел стоит неизвестная цифра x или неизвестно основание p. Подбираем его так, чтобы выполнялось условие.

Значение 46x19₂₉ + 3x85₂₉ делится на 28. Найдите частное для наименьшего x.

Оба вида решаются перебором. Числа вроде 9**100 Python считает точно и быстро, поэтому хитрых формул не нужно.

Ответы к примерам

В первом примере 20 цифр больше 9. Во втором подходят x = a и x = o, для наименьшего частное 109490.

Раздел 2 из 7

База: int, printable и остатки

1. int: читаем запись в системе

int(строка, основание) переводит запись из системы с основанием до 36 в обычное число.

python
print(int('7ea', 16))
print(int('z', 36))

2. printable: все цифры системы

Строка printable начинается с цифр от 0 до 9, а за ними идут маленькие буквы от a до z. Поэтому printable[:29] это все цифры 29-ричной системы, а printable.index('w') показывает значение цифры w.

python
from string import printable

print(printable[:29])
print(printable.index('w'))

3. Остатки: достаём цифры числа

x % k это последняя цифра числа в системе с основанием k. x //= k отрезает её. Повторяем, пока число не кончится.

python
x = 2026
while x != 0:
    print(x % 16)   # цифры идут с конца
    x //= 16

Получили 10, 14, 7 и это те самые 7ea из первого примера, только с конца: a это 10, e это 14.

4. Своя функция перевода

int работает только до основания 36. Если нужно основание больше, пригодится своя функция: каждая цифра умножается на основание в своей степени.

python
def f(x, o):
    return sum(int(c, 36) * o ** i for i, c in enumerate(reversed(x)))

print(f('7ea', 16))
print(f('z', 36))

reversed(x) идёт с последней цифры, enumerate даёт её номер i, это и есть степень основания.

Попробуй самучебная задача

Переведи запись 1g из системы с основанием 20 в десятичную.

Раздел 3 из 7

Считаем цифры в записи

Считаем выражение целиком, потом разбираем его на цифры остатками.

python
x = 5 * 27 ** 20 + 3 * 9 ** 30 - 2    # выражение из условия
count = 0
while x != 0:
    if x % 27 > 9:                     # цифра больше 9 (в записи была бы буквой)
        count += 1
    x //= 27
print(count)

Для другого вопроса меняется только то, что внутри цикла:

Что спрашиваютЧто пишем
Сколько цифр 6 в семеричной записиif x % 7 == 6: count += 1
Сумма цифр в пятеричной записиs += x % 5
Сколько различных цифрs = set(), в цикле s.add(x % 5), потом len(s)
Чётные цифрыif x % 36 % 2 == 0: count += 1. Цифра 0 тоже чётная
Чётные цифры больше 9d = x % 27, потом if d % 2 == 0 and d > 9
Ловушка: большое число не печатается

Если в числе больше 4300 десятичных цифр, print(x) упадёт с ошибкой Exceeds the limit. Само число считается нормально, и остатки тоже работают. Просто не печатай его целиком.

Попробуй самучебная задача

Значение выражения 3·81²⁵ + 2·27²⁰ − 5 записали в системе счисления с основанием 9. Сколько цифр 8 в этой записи?

Раздел 4 из 7

Неизвестная цифра x

Цифры берём из printable, подставляем в запись через f-строку и читаем через int.

python
from string import printable

for x in printable[:29]:                   # все цифры 29-ричной системы
    x1 = int(f'46{x}19', 29)
    x2 = int(f'3{x}85', 29)
    if (x1 + x2) % 28 == 0:
        print(x, printable.index(x), (x1 + x2) // 28)

Подходят a (значение 10, частное 109490) и o (значение 24, частное 110331). Значения идут по возрастанию, поэтому наименьшему x соответствует первая строка вывода, а наибольшему последняя.

Ловушка

Печатай то, что спросили. Чаще всего просят не сам x, а частное. И дели через //: обычное / на таких числах даст неточную дробь.

Попробуй самучебная задача

Значение выражения 3x7₁₇ + 5x3₁₇ делится на 16 при нескольких значениях цифры x. Для наибольшего из них найди частное от деления на 16.

Раздел 5 из 7

Неизвестное основание и основание больше 36

Неизвестное основание p

Перебираем основание от допустимого минимума до 36. Минимум определяет самая большая цифра в записи: основание должно быть больше неё.

python
for p in range(13, 37):                    # цифра c это 12, значит p не меньше 13
    x1 = int('2b', p)
    x2 = int('9c', p)
    x3 = int('6', p)
    if (x1 + x2 + x3) % 17 == 0:
        print(p, (x1 + x2 + x3) // 17)

Подходят p = 19 (частное 14) и p = 36 (частное 25). Начать с меньшего основания нельзя: int('9c', 12) падает с ошибкой ValueError, такой цифры в этой системе нет.

Основание больше 36

int читает только до 36, поэтому число собираем руками: цифра умножается на основание в нужной степени.

python
for x in range(45):                        # цифра x в системе 45: от 0 до 44
    x1 = 7 * 45 ** 2 + x * 45 + 4          # число из цифр 7, x, 4
    x2 = 1 * 45 ** 2 + 40 * 45 + x         # число из цифр 1, 40, x
    if (x1 + x2) % 44 == 0:
        print(x, (x1 + x2) // 44)

Если цифра в условии записана буквой, её значение даёт int('J', 36). Большие и маленькие буквы тут значат одно и то же.

Попробуй самучебная задача

Значение выражения 4ap + 2bp + 7p делится на 13. Цифры a и b обозначают числа 10 и 11. Для наименьшего подходящего p найди частное от деления на 13.

Раздел 6 из 7

Перебор x: ровно N нулей

В выражении есть неизвестное x, и нужно такое x, при котором в записи ровно N нужных цифр. Соединяем два приёма: снаружи цикл по x, внутри разбор на цифры.

python
for x in range(1, 3001):
    n = 7 * 13 ** 150 + 13 ** 100 - 4 * 13 ** 30 - x
    count = 0
    while n:                               # пока n не ноль
        if n % 13 == 0:                    # нулевая цифра
            count += 1
        n //= 13
    if count == 53:
        print(x)

Цикл идёт по 3000 числам, а работает быстро. Если подходит несколько x, вывод будет длинным: наименьшее x это первая строка, наибольшее последняя.

Бывает, что N заранее неизвестно: «при котором нулей максимально». Тогда сначала считаем нули для всех x, запоминаем максимум и его x. Знак >= нужен, если просят наибольшее x: при равном количестве нулей ответ обновляется.

python
best = 0
ans = 0
for x in range(1, 1001):
    n = 3 ** 60 + 3 ** 30 - x
    count = 0
    while n:
        if n % 3 == 0:
            count += 1
        n //= 3
    if count >= best:          # для наименьшего x здесь был бы знак >
        best = count
        ans = x
print(best, ans)
Попробуй самучебная задача

Значение выражения 5·11¹²⁰ + 11⁸⁰ − x, где x это целое число от 1 до 1500, записали в системе счисления с основанием 11. При каком x в записи больше всего нулей?

Раздел 7 из 7

Ловушки и домашка

ЛовушкаКак не попасться
/ вместо //Деление нацело только через //
Степень через ^Степень это **
Цифра не меньше основанияint('c', 12) падает, нижняя граница p выше самой большой цифры
Напечатали не тоЧасто просят частное, а не x
Наибольшее или наименьшееСначала посмотри весь вывод, потом выбирай строку
Чётные цифры0 это тоже чётная цифра
Огромное число в printПечатай результат, а не само число

Как решать задачу

  1. Выпиши выражение как есть, степени через **.
  2. Определи основание и что считать: нули, цифры больше 9, сумму, различные.
  3. Если есть неизвестное, задай перебор: x по printable[:основание], основание p до range(…, 37).
  4. Печатай то, что просят: само x, частное или число цифр.

Домашка

Шесть задач с настоящих экзаменов и из банка ФИПИ. Решай прямо здесь: кнопка «Решать здесь» открывает редактор, а код каждой задачи сохраняется.

Где теряют балл в этих задачах

В первых двух ответ это частное, а не x. Во второй нужно наибольшее значение x, а в первой наименьшее. В четвёртой при равном числе нулей берём больший x. В пятой считается и цифра 0.

Ещё задачи этого вида лежат в разделе «Задания», №14.

Задачи «Попробуй сам» учебные, в домашке задачи с настоящих экзаменов и из банка ФИПИ. Код в блоках можно менять и запускать, он выполняется прямо в браузере.