1 条题解
-
0
题解:机器人指令系统模拟
问题分析
我们需要模拟一个复杂的机器人指令系统,包含:
- 个机器人围成一圈
- 每个机器人有左右手,指向其他机器人
- 每个机器人有 条指令
- 指令会修改机器人的指向、交换/修改指令、激活其他机器人等
- 特殊的 TRIGGER 指令在条件满足时触发
这是一个典型的大模拟题,需要仔细处理各种指令的语义和交互。
1. 核心数据结构
机器人结构:
struct Robot { int left_hand, right_hand; // 当前指向的机器人编号 vector<Command> commands; // m条指令 };指令结构:
struct Command { string type; // 指令类型 int h, x, y, z; // 参数 string command_name; // 对于TRIGGER Command base_cmd; // 对于TRIGGER,存储基础指令 bool is_trigger; // 是否是TRIGGER指令 };
2. 指令解析
需要解析各种指令格式:
SLACKOFFMOVE h zSWAP h x yMIRROR h xREPLACE h x <COMMAND>ACTIVATE hTRIGGER <COMMANDNAME>: <COMMAND>
解析时要注意:
- TRIGGER 指令在正常执行时被跳过
- 其他指令正常执行
3. 执行流程
主循环:
int current_robot = 0; // 当前激活的机器人 int executed_count = 0; // 已执行的指令数 while (executed_count < k) { // 激活当前机器人 activate_robot(current_robot); // 移动到下一个机器人(循环) current_robot = (current_robot + 1) % n; }激活机器人:
void activate_robot(int robot_id) { Robot& robot = robots[robot_id]; for (int i = 0; i < robot.commands.size(); i++) { if (executed_count >= k) return; Command& cmd = robot.commands[i]; // TRIGGER指令在正常执行时跳过 if (cmd.is_trigger) continue; // 执行指令 execute_command(robot_id, cmd); executed_count++; // 检查TRIGGER触发 check_triggers(robot_id, cmd); } }
4. 指令执行
MOVE h z:
int target; if (h == 0) { // 左手 target = (robot.left_hand + z) % n; robot.left_hand = target; } else { // 右手 target = (robot.right_hand + z) % n; robot.right_hand = target; } cout << "Robot " << robot_id << " moves its " << (h == 0 ? "left" : "right") << " hand towards Robot " << target << "." << endl;SWAP h x y:
int target_id = (h == 0) ? robot.left_hand : robot.right_hand; swap(robots[target_id].commands[x-1], robots[robot_id].commands[y-1]); cout << "Robot " << robot_id << " swaps a line of command with Robot " << target_id << "." << endl;ACTIVATE h:
int target_id = (h == 0) ? robot.left_hand : robot.right_hand; cout << "Robot " << robot_id << " activates Robot " << target_id << "." << endl; activate_robot(target_id); // 递归激活
5. TRIGGER 机制
触发条件:
- 其他机器人执行完指令
- 执行者的右手指向自己
- 匹配指令名称
检查触发:
void check_triggers(int executor_id, const Command& executed_cmd) { Robot& executor = robots[executor_id]; // 遍历所有机器人 for (int i = 0; i < n; i++) { if (i == executor_id) continue; // 不能触发自己 // 检查执行者的右手是否指向这个机器人 if (executor.right_hand != i) continue; Robot& potential_trigger = robots[i]; // 检查这个机器人的TRIGGER指令 for (Command& trigger_cmd : potential_trigger.commands) { if (!trigger_cmd.is_trigger) continue; // 检查指令名称匹配 if (matches_trigger(trigger_cmd.command_name, executed_cmd)) { // 执行基础指令 execute_command(i, trigger_cmd.base_cmd); executed_count++; // 只触发最靠前的一个 break; } } } }名称匹配:
bool matches_trigger(const string& trigger_name, const Command& cmd) { if (trigger_name == "TRIGGER") { return cmd.is_trigger; // 检查是否是TRIGGER触发的指令 } else { return !cmd.is_trigger && cmd.type == trigger_name; } }
6. 特殊处理
MIRROR 对 TRIGGER 的影响:
当 MIRROR 作用于 TRIGGER 指令时,修改其基础指令中的 h 参数:
if (target_cmd.is_trigger) { // 修改基础指令中的h if (target_cmd.base_cmd.h != -1) { target_cmd.base_cmd.h = 1 - target_cmd.base_cmd.h; } }指令的动态修改:
由于 SWAP、REPLACE 会修改指令,我们需要在激活机器人时实时获取当前指令:
// 在activate_robot中直接访问commands数组 // 因为指令可能被其他机器人修改
7. 复杂度分析
- 空间复杂度:,存储所有机器人的指令
- 时间复杂度:,最坏情况下每次执行都要检查所有机器人的TRIGGER
- 在 时可行
8. 样例验证
样例1分析:
2 2 5 0 0 MOVE 1 1 // 右手逆时针移动1位:0->1 MOVE 0 1 // 左手逆时针移动1位:0->1 0 1 TRIGGER MOVE: MOVE 0 1 // 被跳过 SLACKOFF执行过程:
- Robot 0执行MOVE 1 1:右手0->1
- Robot 0执行MOVE 0 1:左手0->1
- Robot 1执行TRIGGER(跳过)
- Robot 1执行SLACKOFF
- 触发Robot 0的TRIGGER(条件:执行MOVE且右手指向0)
输出与样例一致。
9. 实现细节
指令解析函数:
Command parse_command(const string& line) { Command cmd; stringstream ss(line); ss >> cmd.type; if (cmd.type == "TRIGGER") { cmd.is_trigger = true; string colon; ss >> cmd.command_name >> colon; // 解析基础指令 string rest; getline(ss, rest); cmd.base_cmd = parse_command(rest); } else { cmd.is_trigger = false; if (cmd.type == "MOVE" || cmd.type == "MIRROR") { ss >> cmd.h >> cmd.z; } else if (cmd.type == "SWAP") { ss >> cmd.h >> cmd.x >> cmd.y; } else if (cmd.type == "REPLACE") { ss >> cmd.h >> cmd.x; // 解析剩余部分作为新指令 string rest; getline(ss, rest); cmd.base_cmd = parse_command(rest); } else if (cmd.type == "ACTIVATE") { ss >> cmd.h; } // SLACKOFF没有参数 } return cmd; }
10. 完整代码框架
#include <iostream> #include <vector> #include <sstream> #include <string> using namespace std; struct Command { string type; int h = -1, x = -1, y = -1, z = -1; string command_name; Command base_cmd; bool is_trigger = false; }; struct Robot { int left_hand, right_hand; vector<Command> commands; }; vector<Robot> robots; int n, m, k; int executed_count = 0; // 解析指令 Command parse_command(const string& line) { // 实现解析逻辑 } // 执行指令 void execute_command(int robot_id, Command& cmd) { // 根据指令类型执行 } // 检查TRIGGER void check_triggers(int executor_id, Command& executed_cmd) { // 检查所有可能的TRIGGER } // 激活机器人 void activate_robot(int robot_id) { Robot& robot = robots[robot_id]; for (int i = 0; i < m; i++) { if (executed_count >= k) return; Command& cmd = robot.commands[i]; if (cmd.is_trigger) continue; execute_command(robot_id, cmd); executed_count++; check_triggers(robot_id, cmd); } } int main() { cin >> n >> m >> k; robots.resize(n); // 读入机器人信息 for (int i = 0; i < n; i++) { cin >> robots[i].left_hand >> robots[i].right_hand; cin.ignore(); for (int j = 0; j < m; j++) { string line; getline(cin, line); robots[i].commands.push_back(parse_command(line)); } } // 主循环 int current_robot = 0; while (executed_count < k) { activate_robot(current_robot); current_robot = (current_robot + 1) % n; } return 0; }
总结
本题的关键在于:
- 仔细理解各种指令的语义和交互
- 正确处理TRIGGER的触发条件和匹配规则
- 处理指令执行过程中的动态修改
- 实现清晰的模块化代码结构
这是一个典型的大模拟题,考察对复杂规则的理解和代码实现能力。
- 1
信息
- ID
- 5563
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者