Редакция для Расшифрование ROT-14


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. Идея

Нужно расшифровать строку, зашифрованную методом ROT-14.

Это означает:

  • каждая заглавная латинская буква была сдвинута на 14 позиций вперёд;
  • чтобы восстановить исходный текст, нужно сдвинуть каждую такую букву на 14 позиций назад;
  • если при сдвиге выходим за пределы алфавита, нужно перейти по кругу.

Пробелы и любые не-буквенные символы менять не нужно.


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

Рассмотрим алфавит из 26 заглавных латинских букв.

Удобно заменить каждую букву её номером:

  • A0
  • B1
  • ...
  • Z25

Тогда расшифровка буквы сводится к формуле:

  • берём номер буквы x
  • считаем новый номер: (x - 14 + 26) % 26

Почему добавляется 26:

  • если просто сделать x - 14, можно получить отрицательное число;
  • добавление 26 позволяет корректно сделать циклический переход.

Например:

  • A имеет номер 0
  • 0 - 14 = -14
  • -14 + 26 = 12
  • 12 — это M

Значит, A расшифровывается в M.

Если символ не является заглавной латинской буквой, его просто копируем в ответ без изменений.


3. Алгоритм

  1. Считать всю строку целиком.
  2. Создать пустую строку ответа.
  3. Для каждого символа строки:
    • если это буква от A до Z:
      • перевести её в номер от 0 до 25;
      • сдвинуть на 14 назад по формуле (x - 14 + 26) % 26;
      • превратить обратно в букву;
      • добавить в ответ;
    • иначе:
      • просто добавить символ в ответ.
  4. Вывести полученную строку.

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

Докажем, что алгоритм действительно выполняет расшифровку ROT-14.

При шифровании каждая буква заменяется на букву, находящуюся на 14 позиций вперёд по циклическому алфавиту.

Если номер исходной буквы равен x, то после шифрования получится номер:

(x + 14) % 26

Чтобы вернуть исходную букву, нужно выполнить обратное действие — вычесть 14 по модулю 26:

((x + 14) - 14) % 26 = x % 26 = x

Именно это и делает алгоритм для каждой заглавной буквы.

Пробелы и другие символы по условию не шифруются, поэтому их нужно оставлять без изменений. Алгоритм делает и это.

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


5. Сложность

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

  • Время работы: O(n), потому что каждый символ обрабатывается один раз.
  • Дополнительная память: O(n), потому что строится строка ответа.

6. Код на C++17

#include <iostream>
#include <string>
using namespace std;

int main() {
    string s;
    getline(cin, s);

    string result;
    for (char c : s) {
        if (c >= 'A' && c <= 'Z') {
            int x = c - 'A';
            x = (x - 14 + 26) % 26;
            result += char('A' + x);
        } else {
            result += c;
        }
    }

    cout << result << '\n';
    return 0;
}

7. Код на Python 3

s = input()

result = []
for c in s:
    if 'A' <= c <= 'Z':
        x = ord(c) - ord('A')
        x = (x - 14) % 26
        result.append(chr(ord('A') + x))
    else:
        result.append(c)

print(''.join(result))

Комментарии

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