这是我很难解决的问题。
给定一个密文 Y 和从字符串 Z 产生 Y 的循环移位序列,带有参数 (i, j, k) 的移位适用于子字符串 Z[i..j](从第 i 个到 j- th 字符,包括)并循环向右旋转 k 次。字符串字符从 1 开始编号。鉴于上述信息,您的任务是猜测初始明文 X。
输入:
第一行包含密文,它是一个由 N 个小写英文字母(1 ≤ N ≤ 50000)组成的非空字符串。第二行包含班次数 M (1 ≤ M ≤ 50000)。以下 M 行描述了循环移位的序列(按照它们应用于明文的顺序)。每个移位由三个参数 i、j、k (1 ≤ i < j ≤ N, 1 ≤ k ≤ j - i) 描述。
输入示例:
logoduck
3
1 3 1
4 5 1
1 4 1
作为输出,您应该提供解密的文本(例如“goodluck”)。
显而易见的方法是尝试从最后一个班次开始反转每个班次。这种方法似乎不省时。但是,我无法想出如何以其他方式做到这一点的任何想法,因此不胜感激。
我附上我的代码:
#include <iostream>
#include <vector>
#include <string>
int main() {
std::string message;
std::cin >> message;
int number_of_elements = message.size();
int elements[number_of_elements];
for (int i = 0; i < number_of_elements; ++i) {
elements[i] = i;
}
int number_of_shifts;
std::cin >> number_of_shifts;
std::vector<std::vector<int>> shifts(number_of_shifts);
for (int iterator = 0; iterator < number_of_shifts; ++iterator) {
int left, right, by;
std::cin >> left >> right >> by;
--left;
--right;
shifts[iterator].push_back(left);
shifts[iterator].push_back(right);
shifts[iterator].push_back(by);
}
for (int iterator = number_of_shifts - 1; -1 < iterator; --iterator) {
int current[number_of_elements];
int left, right, by;
left = shifts[iterator][0];
right = shifts[iterator][1];
by = shifts[iterator][2];
for (int j = right; left - 1 < j; --j) {
if (j - by < left) {
current[right + 1 - (left - (j - by))] = elements[j];
} else {
current[j - by] = elements[j];
}
}
for (int j = left; j < right + 1; ++j) {
elements[j] = current[j];
}
}
for (int i = 0; i < number_of_elements; ++i) {
std::cout << message.substr(elements[i], 1);
}
return 0;
}