机器人OJ

引言

偶然发现LeetCode有七八道关于模拟机器人的OJ试题,心血来潮试做一下,大部分都是利用数学思维解决问题,还挺有意思。

速算机器人

在这里插入图片描述

分析

这道题应该没什么问题,基础的字符串识别

从左至右检测字符串
检测到A执行x = 2*x + y;
检测到B执行y = 2*y + x;

code

int calculate(char* s){
    int x = 1,y = 0;
    while(*s){
        if(*s == 'A')
            x = 2*x + y;
        else
            y = 2*y + x;
        s++;
    }
    return x+y;
}

模拟行走机器人

在这里插入图片描述
在这里插入图片描述

分析

这道题就用模拟法做就成了,控制好方向的转变。

4个方向最好按顺时针/逆时针设置,这样容易控制方向。

将障碍利用set处理成障碍集,每次移动在障碍集里查探一下,如果本位置是障碍,则执行下一个命令,否则继续执行当前指令

code

class Solution {
public:
    int dir[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};//上右下左--顺时针方向转 
    int robotSim(vector<int>& commands, vector<vector<int>>& obstacles) {
        int distance = 0;
        int x = 0,y = 0;
        int sz = commands.size();
        int pt = 0;
        set<pair<int, int>> obstacleSet;
        for(int i=0;i<obstacles.size();i++)
            obstacleSet.insert(make_pair(obstacles[i][0], obstacles[i][1]));
        for(int i = 0;i<sz;++i){
            if(commands[i] == -1)
                pt = pt == 3?0:pt+1;
            else if(commands[i] == -2)
                pt = (!pt)?3:pt-1;
            else{
                for(int k = 0;k<commands[i];k++){
                    int nx = x + dir[pt][0];
                    int ny = y + dir[pt][1];
                    if (obstacleSet.find(make_pair(nx, ny)) == obstacleSet.end()) {
                        x = nx;
                        y = ny;
                        distance = max(distance, x*x + y*y);
                    }
                    else
                        break;
                }  
            }
        }
        return distance;
    }
};

机器人能否返回原点

在这里插入图片描述

在这里插入图片描述

分析

这道题,哎呀,没什么说的,字符串检测问题。

code

class Solution {
public:
    bool judgeCircle(string moves) {
        int sz = moves.size();
        int x = 0,y = 0;
        for(int i = 0;i<sz;i++){
            if(moves[i] == 'U')
                ++y;
            else if(moves[i] == 'D')
                --y;
            else if(moves[i] == 'L')
                --x;
            else
                ++x;
        }
        return !x && !y;
    }
};

机器人大冒险

在这里插入图片描述

在这里插入图片描述

分析

利用数学方法将终点和障碍划拉到第一次命令循环的步骤中,然后模拟第一次命令的执行,检测终点和障碍集。

code

class Solution {
public:
    bool robot(string command, vector<vector<int>>& obstacles, int x, int y) {
        int n = command.size(), m = obstacles.size(), cX = 0, cY = 0;
        for(int i = 0; i < n; ++i){ // O(n),统计一个循环需要x和y能走多远
            if(command[i] == 'U') cY++;
            else cX++;
        }
        for(int i = 0; i < m; ++i){ // O(m),计算每一个障碍物会不会碰到
            int oX = obstacles[i][0], oY = obstacles[i][1];
            if(oX > x || oY > y) continue; // 障碍物在终点之外
            int cnt = min(oX / cX, oY / cY); // 到障碍物至少需要多少个完整循环
            oX -= cnt * cX, oY -= cnt * cY;
            if(oX == 0 && oY == 0) return false; // 刚好cnt个完整循环到障碍物
            for(int j = 0; j < n; ++j){ // O(n)
                if(command[j] == 'U') oY--;
                else oX--;
                if(oX == 0 && oY == 0) return false; // 碰到障碍物
                if(oX < 0 || oY < 0) break; // 碰不到障碍物的情况
            }
        }
        int cycle = min(x/ cX, y / cY); // 到终点至少需要多少个循环
        x -= cycle * cX, y -= cycle * cY;
        if(x == 0 && y == 0) return true; // 刚好cycle个完整循环可以到终点
        for(int i = 0; i < n; ++i){ // O(n)
            if(command[i] == 'U') y--;
            else x--;
            if(x==0 && y == 0) return true; // 能到终点
            if(x < 0 || y < 0) return false; // 不能到终点
        }
        return true;
    }
};

机器人的运动范围

在这里插入图片描述

分析

DFS走起来!

code

class Solution {
public:
    int movingCount(int m, int n, int k) {
        if(k<0 || m<=0 || n<= 0)
            return 0;
        vector<vector<bool>> visited(m,vector<bool> (n,false));
        int cnt = CheckCore(0,0,k,visited,m,n);
        return cnt; 
    }
    private:
    int CheckCore(const int& row,const int& col,const int& k,vector<vector<bool>>& visited,const int& m,const int& n){
        int cnt = 0;
        if(Check(row,col,k,visited,m,n)){
            visited[row][col] = true;
            cnt = 1+CheckCore(row-1,col,k,visited,m,n)+CheckCore(row+1,col,k,visited,m,n)+
                CheckCore(row,col-1,k,visited,m,n)+CheckCore(row,col+1,k,visited,m,n);
        }
        return cnt;
    }
    bool Check(const int& row,const int& col,const int& k,vector<vector<bool>>& visited,const int& m,const int& n){
        if(row>=0&&row<m&&col>=0&&col<n&&GetAdd(row,col,k)&&!visited[row][col])
            return true;
        return false;
    }
    bool GetAdd(int row,int col,const int& k){
        int res = 0;
        while(row){
            res+=row%10;
            row/=10;
        }
        while(col){
            res+=col%10;
            col/=10;
        }
        return res<=k;
    }
};

迷路的机器人

在这里插入图片描述

分析

回溯大法好!

code

class Solution {
public:
    vector<vector<int>> res;
    vector<vector<int>> pathWithObstacles(vector<vector<int>>& obstacleGrid) {
        r = obstacleGrid.size(),c = obstacleGrid[0].size();
        if(!r || !c || obstacleGrid[r-1][c-1])
            return res;
        vector<vector<bool>> vis(r,vector<bool>(c,true));
        BackTrack(0,0,obstacleGrid,vis);
        return res;
    }
    private:
    int r,c;
    bool BackTrack(int row,int col,const vector<vector<int>>& ob,vector<vector<bool>>& vis){
        int sz = res.size();
        if(sz>0 && res[sz-1][0]==r-1 && res[sz-1][1]==c-1)//已到终点
            return true; 
        if(row>=r || col>=c || ob[row][col] || !vis[row][col])//剪枝
            return false;
        res.push_back(vector<int> ({row,col}));
        if(BackTrack(row+1,col,ob,vis) || BackTrack(row,col+1,ob,vis))//一个方向即可
            return true;
        vis[row][col] = false;
        res.pop_back();
        return false;
    }
};

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值