我是吴京 2022-02-19 10:48 采纳率: 67.4%
浏览 40
已结题

请问我哪里出问题了?力扣杯31.变换的迷宫

题目:https://leetcode-cn.com/problems/Db3wC1/

class Solution {
private:
    vector<vector<int>>udlr = {{1, 0}, {-1, 0}, {0, -1}, {0, 1}, {0, 0}}; // 往上下左右走
    int limittime;
    vector<int>rightPos;
    
    int dp[51][51][101][2][2] = {0}; // dp数组 1代表失败,0代表未记录

public:
    bool goMaze(vector<vector<string>>& maze, vector<int>pos, int time, bool used1, bool used2){ // pos代表位置,time代表时间,used1表示临时小时术,used2表示永久消失术
        int cury = pos[0], curx = pos[1]; // 当前位置

        if(dp[cury][curx][time][used1][used2]) return false; // 动态规划

        //失败条件:当前时间耗尽且位置不在终点
        if(time == limittime && (cury != this->rightPos[0] || curx != this->rightPos[1])) return false;

        //成功条件:位置在终点
        if(cury == this->rightPos[0] && curx == this->rightPos[1]) return true;

        int nexttime = time+1; // 当时间为limittime 且 未到达终点则失败
 
        // 1.走的情况:枚举上下左右走
        for(vector<int> &vec : udlr){
            int nexty = cury + vec[0]; // 下一个位置的y坐标
            int nextx = curx + vec[1]; // 下一个位置的x坐标

            // 看下一个位置是否在地图里,如果不是则continue循环
            if(nextx < 0 || nextx > rightPos[1] || nexty < 0 || nexty > rightPos[0]) continue;

            //判断下一个位置的合法性,并选择是否使用卷轴

            // 可能性1:下一个位置不是陷阱 情况:1)走
            if(maze[nexttime][nexty][nextx] == '.'){
                if(goMaze(maze, {nexty, nextx}, nexttime, used1, used2)) return true; // 走
            }

            // 可能性2:下一个位置是陷阱 情况:1)使用道具
            else{
                if(used1){ // 使用道具1
                    if(goMaze(maze, {nexty, nextx}, nexttime, !used1, used2)) return true;
                }
                if(used2){ // 使用道具2
                    vector<int>vec1 = changeMap(maze, nexty, nextx);
                    if(goMaze(maze, {nexty, nextx}, nexttime, used1, !used2)) return true;
                    recoverMap(maze, nexty, nextx, vec1); // !
                }
            }
        }

        // 四个方向 或者不走 都走不了,返回走不了
        dp[cury][curx][time][used1][used2] = 1;
        return false;
    }

    vector<int> changeMap(vector<vector<string>>& maze, int y, int x){
        vector<int>vec1; int count = 0;
        for(vector<string> &vec : maze){
            if(vec[y][x] == '#') vec1.push_back(count);
            count++; vec[y][x] = '.';
        }
        return vec1;
    }

    void recoverMap(vector<vector<string>>& maze, int y, int x, vector<int>vec){
        for(int i : vec) maze[i][y][x] = '#';
    }

    bool escapeMaze(vector<vector<string>>& maze) {
        this->limittime = maze.size()-1;
        int yLength = maze[0].size(), xLength = maze[0][0].size();
        this->rightPos = {yLength-1, xLength-1};

        if(goMaze(maze, {0, 0}, 0, true, true)) return true;
        else return false;
    }
};

  • 写回答

1条回答 默认 最新

  • 爱在凌晨 2022-02-22 17:40
    关注

    udlr 改了下,再加了个剪枝,虽然改了下过了,但是不知道问题是啥

    class Solution {
    private:
        //vector<vector<int>>udlr = {{1, 0}, {-1, 0}, {0, -1}, {0, 1}, {0, 0}}; // 往上下左右走
        vector<vector<int>>udlr = { {-1,0},{0,1},{1,0},{0,0},{0,-1}}; // 往上下左右走
        int limittime;
        vector<int>rightPos;
        
        int dp[51][51][101][2][2] = {0}; // dp数组 1代表失败,0代表未记录
     
    public:
        bool goMaze(vector<vector<string>>& maze, vector<int>pos, int time, bool used1, bool used2){ // pos代表位置,time代表时间,used1表示临时小时术,used2表示永久消失术
            int cury = pos[0], curx = pos[1]; // 当前位置
            if(curx + cury + limittime - time < rightPos[0] + rightPos[1] - 2)
                return false;
            if(dp[cury][curx][time][used1][used2]) return false; // 动态规划
     
            //失败条件:当前时间耗尽且位置不在终点
            if(time == limittime && (cury != this->rightPos[0] || curx != this->rightPos[1])) return false;
     
            //成功条件:位置在终点
            if(cury == this->rightPos[0] && curx == this->rightPos[1]) return true;
     
            int nexttime = time+1; // 当时间为limittime 且 未到达终点则失败
     
            // 1.走的情况:枚举上下左右走
            for(vector<int> &vec : udlr){
                int nexty = cury + vec[0]; // 下一个位置的y坐标
                int nextx = curx + vec[1]; // 下一个位置的x坐标
     
                // 看下一个位置是否在地图里,如果不是则continue循环
                if(nextx < 0 || nextx > rightPos[1] || nexty < 0 || nexty > rightPos[0]) continue;
     
                //判断下一个位置的合法性,并选择是否使用卷轴
     
                // 可能性1:下一个位置不是陷阱 情况:1)走
                if(maze[nexttime][nexty][nextx] == '.'){
                    if(goMaze(maze, {nexty, nextx}, nexttime, used1, used2)) return true; // 走
                }
     
                // 可能性2:下一个位置是陷阱 情况:1)使用道具
                else{
                    if(used1){ // 使用道具1
                        if(goMaze(maze, {nexty, nextx}, nexttime, !used1, used2)) return true;
                    }
                    if(used2){ // 使用道具2
                        vector<int>vec1 = changeMap(maze, nexty, nextx);
                        if(goMaze(maze, {nexty, nextx}, nexttime, used1, !used2)) return true;
                        recoverMap(maze, nexty, nextx, vec1); // !
                    }
                }
            }
     
            // 四个方向 或者不走 都走不了,返回走不了
            dp[cury][curx][time][used1][used2] = 1;
            return false;
        }
     
        vector<int> changeMap(vector<vector<string>>& maze, int y, int x){
            vector<int>vec1; int count = 0;
            for(vector<string> &vec : maze){
                if(vec[y][x] == '#') vec1.push_back(count);
                count++; vec[y][x] = '.';
            }
            return vec1;
        }
     
        void recoverMap(vector<vector<string>>& maze, int y, int x, vector<int>vec){
            for(int i : vec) maze[i][y][x] = '#';
        }
     
        bool escapeMaze(vector<vector<string>>& maze) {
            this->limittime = maze.size()-1;
            int yLength = maze[0].size(), xLength = maze[0][0].size();
            this->rightPos = {yLength-1, xLength-1};
     
            if(goMaze(maze, {0, 0}, 0, true, true)) return true;
            else return false;
        }
    };
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 3月3日
  • 已采纳回答 2月23日
  • 创建了问题 2月19日

悬赏问题

  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器