Редакция для Расшифрование ROT-14
Submitting an official solution before solving the problem yourself is a bannable offence.
1. Идея
Нужно расшифровать строку, зашифрованную методом ROT-14.
Это означает:
- каждая заглавная латинская буква была сдвинута на
14позиций вперёд; - чтобы восстановить исходный текст, нужно сдвинуть каждую такую букву на
14позиций назад; - если при сдвиге выходим за пределы алфавита, нужно перейти по кругу.
Пробелы и любые не-буквенные символы менять не нужно.
2. Наблюдения
Рассмотрим алфавит из 26 заглавных латинских букв.
Удобно заменить каждую букву её номером:
A→0B→1- ...
Z→25
Тогда расшифровка буквы сводится к формуле:
- берём номер буквы
x - считаем новый номер:
(x - 14 + 26) % 26
Почему добавляется 26:
- если просто сделать
x - 14, можно получить отрицательное число; - добавление
26позволяет корректно сделать циклический переход.
Например:
Aимеет номер00 - 14 = -14-14 + 26 = 1212— этоM
Значит, A расшифровывается в M.
Если символ не является заглавной латинской буквой, его просто копируем в ответ без изменений.
3. Алгоритм
- Считать всю строку целиком.
- Создать пустую строку ответа.
- Для каждого символа строки:
- если это буква от
AдоZ:- перевести её в номер от
0до25; - сдвинуть на
14назад по формуле(x - 14 + 26) % 26; - превратить обратно в букву;
- добавить в ответ;
- перевести её в номер от
- иначе:
- просто добавить символ в ответ.
- если это буква от
- Вывести полученную строку.
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))
Комментарии