Найти в Дзене
Стив Май

Разбор ЕГЭ. Информатика. Задача №5

Оглавление

+Оглавление

Разбираем задачу №5 в ЕГЭ по информатике.

Обратите внимание, здесь будет не только пример решения, но и разбор задания по существу.

Для примера я беру демоверсию 2020 года (актуальная на момент написания статьи) с сайта fipi.ru.

Задание №5
Задание №5

Прежде чем приступать к решению этого примера, посмотрим в спецификацию к демоверсии.

Спецификация
Спецификация

От нас требуется закодировать или декодировать информацию за две минуты.

Кодификатор
Кодификатор

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

Немного о кодах и шифрах

Эти слова часто путают. Кратко, разница в них такая: коды известны всем, а шифры секретны.

В наших задачах идёт речь именно о кодах и кодировании. Не вдаваясь в точное формальное определение, скажу, что код - "как заменить символы на другие". В детстве все играли в разведчиков (или ещё как), отправляя друг другу записочки "так, чтобы никто не прочитал". Кто-то заменял буквы на следующие по порядку в алфавите, кто-то просто номера по алфавиту писал. Герои рассказов о Шерлоке Холмсе использовали "пляшущих человечков". Полноценным шифрованием такой процесс трудно назвать, а вот кодированием - запросто. Запись одних символов через другие.

Важно: одна буква может кодироваться целым словом или набором цифр
Пример кодирования с элементами шифрования (большие и маленькие различаются)
Пример кодирования с элементами шифрования (большие и маленькие различаются)

Если Вашу таблицу кодов опубликовать, то трудностей ведь не будет, чтобы прочитать весь текст, не так ли?

В какой-то степени, от нас требуют того же на экзамене, но правила тут чуть менее привычные.

Нам даётся не вся таблица кодов, в которой каждой букве указан её код, а только её часть, и даётся условие, по которому её можно составлять и дальше.

Равномерный и неравномерный код

В своём примере я использовал коды отдельно для букв и писал их по клеточкам. Часто требуется использовать "сплошной" код, то есть такой, которые не надо распихивать по клеточкам, а приходится расшифровывать надо без разделителей между буквами. Вот так примерно:

Код
Код

Как тут определять, где закончилась одна буква, а где следующая началась? Надо знать о длине кода для каждой буквы. В моём случае - по 8 символов.

Разбиение
Разбиение

Кодовые слова:

Таблица кодов
Таблица кодов

Восстановить текст теперь может каждый желающий. Как, в прочем, и зашифровать обратно.

Расшифровка
Расшифровка

А есть коды, в которых одна буква кодируется двумя символами, а вторая - восемью, например, как азбука Морзе. Такие коды сложны, но нам дают довольно простой вариант с условием Фано. Оно написано в тексте задачи, но не все понимают его. Разжую:

Буква имеет такой код, что её нельзя спутать с началом другой буквы.

Закодировать таким кодом не трудно: просто заменяем букву её кодом. А декодирование идёт хитро:

  • читаем текст сначала,
  • как только прочитанный кусок текста совпал с каким-то кодом, заменяем его буквой и
  • Продолжаем читать с того же места.

Если немного пораскинуть мозгами и головами, то условие довольно очевидным становится. В самом деле, если у нас у букв будут такие коды:

-9

то как мы определим, началась ли уже буква "б", или всё ещё идёт буква "а", например, в таком коде: 11001110? Это может быть и (11001)(110) и (110)(01110). Букву "б" по коду можно спутать с началом кода буквы "а" Нужен "однозначный" код.

Придумывать такой код довольно просто, даже без подбора: нужно пользоваться любой модификацией алгоритма Хаффмана. Ещё раз: подбор никто не отменяет. Разберём самый простой, на мой взгляд, вариант алгоритма:

Построим граф-дерево. Как бы по-проще-то объяснить? Короче, вот такое:

дерево
дерево
Двигаясь сверху вниз мы встречаем либо развилку на две дороги (налево-направо), либо букву.

И теперь нам надо записать маршрут к каждой букве, обозначая "налево" как 1, а "направо" как 0 (или наоборот)

дерево
дерево

Путь до буквы "а" состоит из двух поворотов "налево". То есть, из двух 1. Это и будет кодом этой буквы:

Коды, удовлетворяющие условию Фано
Коды, удовлетворяющие условию Фано
Такой метод даёт 100% гарантии, что условие Фано выполняется.

Решение задачи

Построим теперь дерево для букв из задачи. Смотрите: нам уже даны "маршруты" до некоторых букв:

Дерево для решения
Дерево для решения

При аккуратном составлении мы должны будем нарисовать две "пустые" ветки (чтобы была развилка или буква). Я их серым нарисовал.

Теперь можно к вопросу задачи вернуться. Нам надо найти такой код для буквы "П", чтобы он

  • был самым коротким (и наименьшим)
  • не нарушал условие Фано
  • чтобы можно было впихнуть ещё и букву Р, не нарушив это условие

У нас, собственно, два варианта: впихивать на уже имеющиеся ветки, и дорисовывать новые. Второе - очень трудно для ЕГЭ, поэтому явно тут первое. Тут две возможности: слева по маршруту "10" и справа по маршруту "011". Все остальные пути уже оканчиваются буквами. Ясно, который код подходит?

-14

Если поставить букву "П" слева, то выполнятся все условия.

Ответ: 10.

Заключение

Рисунок всегда более нагляден, чем цифры. Если есть возможность решать задание с помощью графа, я рекомендовал бы именно его. Конечно, как я уже писал, тут можно было бы и подобрать. Перебирая все подряд

-15

Правда, нам тут придётся топать и до кода "011", чтобы убедиться, что букву "Р" есть куда впихнуть.

Если бы "свободная" ветка оставалась бы только одна, то нам пришлось бы дорисовывать:

-16

И уже потом выбирать между "101" и "100". Это как раз относится к фразе "Если таких кодов несколько, укажите код с наименьшим числовым значением"

PS

Понравился разбор - ставьте лайк, подписывайтесь на канал, нас ждут ещё остальные задачи

Наука
7 млн интересуются