1 条题解
-
0
解题思路
题目要求从最终消息推断出原始消息,给定信使的顺序。每个信使在传递消息时都会对消息进行特定的变换。为了从最终消息推断出原始消息,我们需要对每个信使的操作进行逆向操作。具体步骤如下:
-
定义每个信使的逆向操作:
- J先生:将消息的所有字符向左旋转一位。逆向操作是将消息的所有字符向右旋转一位。
- C小姐:将消息的所有字符向右旋转一位。逆向操作是将消息的所有字符向左旋转一位。
- E先生:将消息的左半部分与右半部分交换。如果消息的字符数是奇数,中间的字符保持不变。逆向操作是将消息的右半部分与左半部分交换。
- A先生:将消息反转。逆向操作是将消息再次反转。
- P博士:将消息中的所有数字加1。逆向操作是将消息中的所有数字减1。
- M先生:将消息中的所有数字减1。逆向操作是将消息中的所有数字加1。
-
逆向操作的实现:
- 对于每个信使的操作,实现其逆向操作。
- 从最终消息开始,按照信使顺序的逆序,依次应用每个信使的逆向操作。
-
输入处理:
- 读取输入数据,包括数据集的数量、每个数据集的信使顺序和最终消息。
- 对每个数据集,依次应用逆向操作,最终输出推断出的原始消息。
代码实现
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <vector> #include <queue> #include <map> #include <set> #include <ctime> #include <string> using namespace std; typedef long long ll; // 定义长整型变量的简写 #define INF 0x3f3f3f3f // 定义无穷大的值 #define maxn 1111 // 定义数组的最大长度 #define pi acos(-1.0) // 定义圆周率 // 将字符串的最后一个字符移到第一个位置(J先生的逆向操作) void J(string& str) { char ch = str[str.length() - 1]; // 获取字符串的最后一个字符 str.erase(str.length() - 1, 1); // 删除字符串的最后一个字符 str.insert(0, 1, ch); // 将字符插入到字符串的开头 } // 将字符串的第一个字符移到最后一个位置(C小姐的逆向操作) void C(string& str) { char ch = str[0]; // 获取字符串的第一个字符 str.erase(0, 1); // 删除字符串的第一个字符 str.insert(str.length(), 1, ch); // 将字符插入到字符串的末尾 } // 将消息的左半部分与右半部分交换(E先生的逆向操作) void E(string& str) { int len = str.length(); // 获取字符串的长度 string tmp = str; // 临时保存原始字符串 if (len % 2) // 如果字符串长度为奇数 { char ch = tmp[len / 2]; // 获取中间的字符 str.erase(0, len / 2 + 1); // 删除从开头到中间字符(包含)的部分 str.append(1, ch); // 将中间字符追加到字符串末尾 str.append(tmp, 0, len / 2); // 将原始字符串的前半部分追加到末尾 } else // 如果字符串长度为偶数 { str.erase(0, len / 2); // 删除前半部分 str.append(tmp, 0, len / 2); // 将前半部分追加到末尾 } } // 将字符串反转(A先生的逆向操作) void A(string& str) { reverse(str.begin(), str.end()); // 使用标准库函数反转字符串 } // 将消息中的所有数字减1(P博士的逆向操作) void P(string& str) { int len = str.length(); // 获取字符串的长度 for (int i = 0; i < len; i++) // 遍历字符串 if (str[i] >= '0' && str[i] <= '9') // 如果是数字字符 { str[i]--; // 减一 if (str[i] < '0') // 如果小于0 str[i] = '9'; // 变为9 } } // 将消息中的所有数字加1(M先生的逆向操作) void M(string& str) { int len = str.length(); // 获取字符串的长度 for (int i = 0; i < len; i++) // 遍历字符串 if (str[i] >= '0' && str[i] <= '9') // 如果是数字字符 { str[i]++; // 加一 if (str[i] > '9') // 如果大于9 str[i] = '0'; // 变为0 } } // 根据指令对字符串进行逆向操作 void solve(char dir, string &str) { if (dir == 'J') // 如果指令是'J' C(str); // 调用C函数(J的逆向操作) else if (dir == 'C') // 如果指令是'C' J(str); // 调用J函数(C的逆向操作) else if (dir == 'E') // 如果指令是'E' E(str); // 调用E函数(E的逆向操作) else if (dir == 'A') // 如果指令是'A' A(str); // 调用A函数(A的逆向操作) else if (dir == 'P') // 如果指令是'P' M(str); // 调用M函数(P的逆向操作) else // 如果指令是'M' P(str); // 调用P函数(M的逆向操作) } int main() { int n; // 定义测试用例的数量 char dir[7]; // 定义指令字符串 scanf("%d", &n); // 读取测试用例数量 while (n--) // 遍历每个测试用例 { scanf("%s", dir); // 读取指令字符串 int len = strlen(dir); // 获取指令字符串的长度 string msg; // 定义消息字符串 cin >> msg; // 读取消息字符串 for (int i = len - 1; i >= 0; i--) // 从指令字符串的末尾开始遍历 { solve(dir[i], msg); // 对消息字符串进行逆向操作 } cout << msg << endl; // 输出最终结果 } return 0; // 程序结束 }
注释说明
- J、C、E、A、P、M函数:分别实现了每个信使的逆向操作。
- solve函数:根据信使的指令调用相应的逆向操作函数。
- main函数:读取输入数据,依次对每个数据集的消息进行逆向操作,最终输出推断出的原始消息。
-
- 1
信息
- ID
- 1042
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 12
- 已通过
- 1
- 上传者