当前位置: 首页 > 知识库问答 >
问题:

Leetcode问题489。机器人房间清洁器-为什么我的解决方案不起作用

笪智志
2023-03-14

我正在努力解决Leetcode问题489。机器人房间清洁器使用回溯。具体来说,我尝试在四个方向中的每一个方向移动机器人,如果四个方向都被阻塞或清理,则返回。

下面的代码不起作用,我正试图用这个简单的示例对其进行调试:

grid = [[1,1,1],
        [1,0,1]]

其中1表示机器人可以访问单元,0表示单元被阻止。机器人从这个初始位置开始:

initial_row = 0
initial_col = 1

在我运行代码后,机器人只清洁了网格的右侧部分(c-清洁,d-左脏):

[[d,c,c],
 [d,0,c]]

它似乎正确地返回到单元格[0,1],并尝试移动到左上角(单元格[0,0]),但机器人没有移动。move()返回false,函数在清理左上角之前返回。如果您能给我一些建议,我将不胜感激。

代码:

struct hsh {
  size_t operator() (const pair<int,int>& p) const {
      hash<int> intHash;
      return intHash(p.first) ^ intHash(p.second);
  }  
};

class Solution {
public:
    unordered_set<pair<int, int>, hsh> cleaned;
    vector<int> directions {0, 1, 2, 3}; // up, down, right, left
    
    void cleanRoom(Robot& robot) {
       
        int row_s = 0; // relative start row
        int col_s = 0; // relative start col
            
        clean(row_s, col_s, robot);
    }

    void clean(int row, int col, Robot& robot) {
    
        cleaned.insert({row, col});
        robot.clean();
    
        for (int dir : directions) {
        
            if (!is_cleaned(row, col, dir)) {
                turn(robot, dir);
            
                if (robot.move()) {
                    turn_back(robot, dir);
                
                    int row_new = get_new_row(row, dir);
                    int col_new = get_new_col(col, dir);
                
                    clean(row_new, col_new, robot);
                } else {
                    turn_back(robot, dir);
                }
            }
        }
    }

    bool is_cleaned(int row, int col, int dir) {
        int row_new = get_new_row(row, dir);
        int col_new = get_new_col(col, dir);
            
        if(cleaned.find({row_new, col_new}) != cleaned.end()) {
            return true;
        }
        return false;
    
    }

    void turn(Robot& robot, int dir) {
        if (dir == 0) { // up
        } else if (dir == 1) { // down
            robot.turnLeft();
            robot.turnLeft();
        } else if (dir == 2) { // right
            robot.turnRight();
        } else { // left
            robot.turnLeft();
        }
    }

    void turn_back(Robot& robot, int dir) {
        if (dir == 0) { // back to up from up
        } else if (dir == 1) { // back to up from down
            robot.turnLeft();
            robot.turnLeft();
        } else if (dir == 2) { // back to up from right
            robot.turnLeft();
        } else { // back to up from left
            robot.turnRight();
        }
    }

    int get_new_row(int row, int dir) {
        if (dir == 0) { // up
            row--; 
            return row;
        } else if (dir == 1) { // down
            row++; 
            return row;
        }
    
        return row;
    }

    int get_new_col(int col, int dir) {
        if (dir == 2) { // right
            col++; 
            return col;
        } else if (dir == 3) { // left
            col--; 
            return col;
        }
    
        return col;
    }
};

共有1个答案

苏培
2023-03-14

问题在于,机器人类接口在回溯时不会自动将机器人放回原位(机器人对象通过引用传递并保持其位置)。添加了一个特定的功能,在回溯后将机器人移回修复了该问题:

void go_back(Robot& robot, int dir) {
    // Keep mind that the robot always ends up facing up after every move
    if (dir == 0) { // moved up - returning down
        robot.turnLeft();
        robot.turnLeft();
        robot.move();
        robot.turnLeft();
        robot.turnLeft();
    } else if (dir == 1) { // moved down - returning up
        robot.move();
    } else if (dir == 2) { // moved right - returning left
        robot.turnLeft();
        robot.move();
        robot.turnRight();
    } else { // moved left - returning right
        robot.turnRight();
        robot.move();
        robot.turnLeft();
    }
}

然后在递归清洁()函数中调用这个函数:

void clean(int row, int col, Robot& robot) {
    
    cleaned.insert({row, col});
    robot.clean();
            
    for (int dir : directions) {
                    
        if (!is_cleaned(row, col, dir)) {
            turn(robot, dir);
            
            if (robot.move()) {
                turn_back(robot, dir);
                
                int row_new = get_new_row(row, dir);
                int col_new = get_new_col(col, dir);
                
                clean(row_new, col_new, robot);
                
                go_back(robot, dir); // Move the robot back while backtracking!
                
            } else {
                turn_back(robot, dir);
            }
        }
    }
    
} 
 类似资料:
  • 对于python我是新手,我正在做leetcode问题94,二叉树顺序遍历。给定二叉树的根,返回对其节点值的inorder遍历。 但我还是不明白它为什么有用。在之后,在递归过程中,res变量不会被重新分配给[]吗?或者res变量在不同的递归中应该是不同的变量吗?

  • 下面的代码是我解决这个问题的尝试。我使用了基于1的索引。我无法找出错误。我试着调试代码,但没有帮助。我已经被困了两天了。请帮忙。

  • 用RXJava解决这个问题的最好方法是什么?我想摆脱UiThread的帖子和列表的前期准备。但将其替换为RXJava特性。

  • 下面是问题的链接:SPOJ-ACTIV 我想出了这个问题的重现如下: 其中next()查找具有开始时间的活动的索引 这是我的java解决方案,虽然它通过了SPOJ工具包的许多测试用例,但是它确实为一些提供了WA。我的概念/解决方案有什么问题?

  • 给定一个二维板和一个单词,找出这个单词是否存在于网格中。 这个词可以由顺序相邻单元格的字母构成,其中“相邻”单元格是那些水平或垂直相邻的单元格。同一个字母单元格不能使用不止一次。 例如,给定 这是典型的DFS+回溯解决方案。它将与进行比较。如果它们匹配,则将更改为以将其标记为已访问。然后移动到下一个(即)并将其与当前邻居进行比较(通过递归进行)。 下面是我的代码,这是不工作。我试着调试,但我觉得在

  • 所以最近我一直在努力思考并发问题。目前,我正在努力寻找读者作家问题的解决方案。 我有一个类文件,它计算读者/作家的数量,并有两个信号量。 当读卡器尝试读取时,只要有写入线程在写入,它就必须等待。当它进入readCount时,readerSemaphore中的readCount会增加 当一个编写器试图进入时,只要有多个读卡器,它就必须等待。当它进入时,获取writerSemaphore并增加writ