C++ 颠倒循环移位的顺序
这是我很难解决的问题 给您一个密文Y和一系列循环移位,这些移位从字符串Z生成Y,带有参数(i,j,k)的移位应用于子字符串Z[i..j](从第i个字符到第j个字符,包括在内),并循环将其向右旋转k次。字符串从一开始编号。根据以上信息,您的任务是猜测初始明文X 输入: 第一行包含密文,它是由N个小写英文字母(1)组成的非空字符串≤ N≤ 50000). 第二行包含移位数M(1≤ M≤ 50000). 以下M行描述了循环移位的顺序(按照其应用于明文的顺序)。每个移位由三个参数i、j、k(1)描述≤ iC++ 颠倒循环移位的顺序,c++,algorithm,decoding,rmq,lowest-common-ancestor,C++,Algorithm,Decoding,Rmq,Lowest Common Ancestor,这是我很难解决的问题 给您一个密文Y和一系列循环移位,这些移位从字符串Z生成Y,带有参数(i,j,k)的移位应用于子字符串Z[i..j](从第i个字符到第j个字符,包括在内),并循环将其向右旋转k次。字符串从一开始编号。根据以上信息,您的任务是猜测初始明文X 输入: 第一行包含密文,它是由N个小写英文字母(1)组成的非空字符串≤ N≤ 50000). 第二行包含移位数M(1≤ M≤ 50000). 以下M行描述了循环移位的顺序(按照其应用于明文的顺序)。每个移位由三个参数i、j、k(1)描述≤
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;
}
#包括
#包括
#包括
int main(){
std::字符串消息;
std::cin>>消息;
int number_of_元素=message.size();
int元素[元素的数量];
for(int i=0;i<元素的个数;++i){
元素[i]=i;
}
整数移位数;
std::cin>>换班次数;
std::向量移位(移位的数量);
for(int迭代器=0;迭代器<移位数;++迭代器){
int left,right,by;
标准::cin>>左>>右>>由;
--左;
--对,;
移位[迭代器]。向后推(左);
移位[迭代器]。向后推(右);
移位[迭代器]。推回(按);
}
for(int迭代器=移位次数-1;-1<迭代器;--迭代器){
int当前[元素的数量];
int left,right,by;
左=移位[迭代器][0];
右=移位[迭代器][1];
by=移位[迭代器][2];
对于(int j=右;左-1
当然,可以通过这些操作构建旋转
实现是一个二叉树、B树或类似的树,叶中的字符串大小有限
不难找到C++实现,但不幸的是,STL没有一个。如果你必须自己实现,那就有点棘手。
[OT]:你可以用<代码> STD::向量< /代码>代替<代码> STD::vector < /COD>。不存在额外的内存(<代码> int流[NoMyByOfOntEng];< /> >无效BTW,VLA扩展)@Jarod42谢谢你的建议!不过,这不会改变复杂性,对吧?你应该仍然在O(N*M)
,但因子可能很重要。(你有1个分配而不是M)谢谢,我会试试这个!