2020-5 leetcode 1263. 推箱子

1.用BFS遍历来得到答案。
难点:1.怎么把人和箱子的状态连接起来(这里用四维数组dist 连接,并且作为标记数组)
2.分析人的下一步对箱子的影响:1.当人的下一步是箱子所处位置时,要明白:箱子所走的方向和人走的方向是一致的。
2.当不是箱子所处位置时,对箱子无影响。
因为是BFS 所以第一次碰到终点时,便是答案

 struct Dwell{
        int box_x,box_y;
        int man_x,man_y;
        Dwell(int _bx,int _by,int _mx,int _my):box_x(_bx),box_y(_by),man_x(_mx),man_y(_my){}
    };

class Solution {
public:
    int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
    int minPushBox(vector<vector<char>>& grid) {
        int m=grid.size();
        int n=grid[0].size();
        int dist[m][n][m][n];
        memset(dist,-1,sizeof(dist));

        int box_x,box_y;
        int start_x,start_y;
        int end_x,end_y;

        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(grid[i][j]=='B'){
                    box_x=i;
                    box_y=j;
                    grid[i][j]='.';
                }
                else if(grid[i][j]=='S'){
                    start_x=i;
                    start_y=j;
                    grid[i][j]='.';
                }
                else if(grid[i][j]=='T'){
                    end_x=i;
                    end_y=j;
                    grid[i][j]='.';
                }
            }
        }

        queue<Dwell> q;
        q.push({box_x,box_y,start_x,start_y});
        dist[box_x][box_y][start_x][start_y]=0;

        while(!q.empty()){
            queue<Dwell> nq;
            
            while(!q.empty()){
                auto cur=q.front();
                q.pop();
            
            for(int i=0;i<4;i++){
                int nxt_x=cur.man_x+dir[i][0];
                int nxt_y=cur.man_y+dir[i][1];

                if(nxt_x>=0&&nxt_x<m&&nxt_y>=0&&nxt_y<n){
                    if(cur.box_x==nxt_x&&cur.box_y==nxt_y){
                        int nxt_box_x=cur.box_x+dir[i][0];
                        int nxt_box_y=cur.box_y+dir[i][1];
                        if(nxt_box_x>=0&&nxt_box_x<m&&nxt_box_y>=0&&nxt_box_y<n){
                            if(grid[nxt_box_x][nxt_box_y]=='.'&&dist[nxt_box_x][nxt_box_y][nxt_x][nxt_y]==-1){
                        nq.emplace(nxt_box_x,nxt_box_y,nxt_x,nxt_y);
                        dist[nxt_box_x][nxt_box_y][nxt_x][nxt_y]=dist[cur.box_x][cur.box_y][cur.man_x][cur.man_y]+1;
                            }
                            if(nxt_box_x==end_x&&nxt_box_y==end_y){
                                return dist[nxt_box_x][nxt_box_y][nxt_x][nxt_y];
                            }

                        }
                    }

                    else{
                        if(grid[nxt_x][nxt_y]=='.'&&dist[cur.box_x][cur.box_y][nxt_x][nxt_y]==-1){
                                q.emplace(cur.box_x,cur.box_y,nxt_x,nxt_y);
                                dist[cur.box_x][cur.box_y][nxt_x][nxt_y]=dist[cur.box_x][cur.box_y][cur.man_x][cur.man_y];
                        }
                    }

                }
      
            }
            }
            q=nq;
        }
        return -1;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值