1 条题解

  • 0
    @ 2025-11-25 8:56:19

    题解:机器人指令系统模拟

    问题分析

    我们需要模拟一个复杂的机器人指令系统,包含:

    • nn 个机器人围成一圈
    • 每个机器人有左右手,指向其他机器人
    • 每个机器人有 mm 条指令
    • 指令会修改机器人的指向、交换/修改指令、激活其他机器人等
    • 特殊的 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. 指令解析

    需要解析各种指令格式:

    • SLACKOFF
    • MOVE h z
    • SWAP h x y
    • MIRROR h x
    • REPLACE h x <COMMAND>
    • ACTIVATE h
    • TRIGGER <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 机制

    触发条件

    1. 其他机器人执行完指令
    2. 执行者的右手指向自己
    3. 匹配指令名称

    检查触发

    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. 复杂度分析

    • 空间复杂度O(n×m)O(n \times m),存储所有机器人的指令
    • 时间复杂度O(k×n×m)O(k \times n \times m),最坏情况下每次执行都要检查所有机器人的TRIGGER
    • n100,m10,k3×105n \leq 100, m \leq 10, k \leq 3\times 10^5 时可行

    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
    

    执行过程:

    1. Robot 0执行MOVE 1 1:右手0->1
    2. Robot 0执行MOVE 0 1:左手0->1
    3. Robot 1执行TRIGGER(跳过)
    4. Robot 1执行SLACKOFF
    5. 触发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;
    }
    

    总结

    本题的关键在于:

    1. 仔细理解各种指令的语义和交互
    2. 正确处理TRIGGER的触发条件和匹配规则
    3. 处理指令执行过程中的动态修改
    4. 实现清晰的模块化代码结构

    这是一个典型的大模拟题,考察对复杂规则的理解和代码实现能力。

    • 1

    信息

    ID
    5563
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者