Редакция для Двойной шестнадцатеричный код в строку


Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.

1. Идея

Нужно снять два одинаковых слоя шестнадцатеричного кодирования.

Один слой работает так:

  • берётся символ,
  • его ASCII-код переводится в шестнадцатеричный вид,
  • записывается ровно двумя символами,
  • все такие пары склеиваются в одну строку.

Если такое преобразование применили два раза, то для восстановления исходного сообщения достаточно:

  1. один раз декодировать входную строку из шестнадцатеричного вида;
  2. ещё раз декодировать полученный результат.

То есть задача сводится к двойному применению одной и той же функции декодирования.

2. Наблюдения

Наблюдение 1

Если строка закодирована одним слоем, то каждые 2 символа в ней — это шестнадцатеричная запись ASCII-кода одного символа.

Например:

  • 41 → символ 'A',
  • 48 → символ 'H',
  • 69 → символ 'i'.

Наблюдение 2

После первого декодирования получится не исходное сообщение, а строка, которая сама является результатом одного шестнадцатеричного кодирования.

Например, для входа 3431:

  • пара 34 означает символ '4',
  • пара 31 означает символ '1'.

Значит, после первого декодирования получаем строку 41.

Но 41 — это тоже шестнадцатеричное представление ASCII-кода символа 'A'.

После второго декодирования получаем A.

Наблюдение 3

По условию гарантируется, что строка корректна и действительно получена таким способом. Значит:

  • длина входа чётная;
  • после первого декодирования тоже получится корректная строка для второго декодирования.

3. Алгоритм

Сделаем функцию decode_hex(s), которая:

  1. идёт по строке s с шагом 2;
  2. берёт очередные два символа;
  3. переводит их из шестнадцатеричной системы в число;
  4. превращает это число в символ;
  5. добавляет символ в ответ.

После этого:

  1. читаем входную строку s;
  2. вычисляем first = decode_hex(s);
  3. вычисляем second = decode_hex(first);
  4. выводим second.

4. Почему это работает

Докажем, что алгоритм восстанавливает исходную строку.

Пусть исходная строка равна T.

После одного кодирования каждый символ строки T заменяется двумя шестнадцатеричными цифрами его ASCII-кода. Получается строка E(T).

После второго кодирования аналогичная операция применяется к строке E(T). Получается итоговая строка E(E(T)). Именно она дана во входных данных.

Функция decode_hex выполняет обратное действие к одному слою кодирования:

  • каждые 2 шестнадцатеричные цифры переводятся в число;
  • это число интерпретируется как ASCII-код символа;
  • из таких символов собирается строка.

Следовательно:

  • decode_hex(E(E(T))) = E(T),
  • decode_hex(E(T)) = T.

Значит, после двух применений decode_hex мы получаем исходную строку T.

Следовательно, алгоритм работает правильно.

5. Сложность

Пусть длина входной строки равна n.

Один вызов decode_hex обрабатывает строку по парам символов, то есть работает за O(n).

Так как декодирование выполняется два раза, общая сложность остаётся линейной: O(n).

Дополнительная память:

  • на результат первого декодирования,
  • на результат второго декодирования.

Итого O(n) дополнительной памяти.

6. Код на C++17

#include <iostream>
#include <string>

using namespace std;

string decode_hex(const string& s) {
    string result;
    result.reserve(s.size() / 2);
    for (size_t i = 0; i < s.size(); i += 2) {
        string part = s.substr(i, 2);
        int value = stoi(part, nullptr, 16);
        result.push_back(static_cast<char>(value));
    }
    return result;
}

int main() {
    string s;
    cin >> s;

    string first = decode_hex(s);
    string second = decode_hex(first);

    cout << second;
    return 0;
}

7. Код на Python 3

def decode_hex(s):
    result = []
    for i in range(0, len(s), 2):
        part = s[i:i + 2]
        value = int(part, 16)
        result.append(chr(value))
    return ''.join(result)

s = input()

first = decode_hex(s)
second = decode_hex(first)

print(second)

Комментарии

Еще нет ни одного комментария.