LC 5529. Cat and Mouse II (gaming/bfs/topo)

link

class Solution {
public:
    struct State{
        int mpos;
        int cpos;
        int turn;
        int win;
        State(int m, int c, int t, int w){
            mpos=m;
            cpos=c;
            turn=t;
            win=w;
        }
    };
    int m,n;
    int fpos;
    int dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
    int memo[64][64][2];
    int degree[64][64][2];
    bool canMouseWin(vector<string>& grid, int catJump, int mouseJump) {
        m=grid.size();
        n=grid[0].size();
        memset(memo,-1,sizeof(memo));
        queue<State> q;
        int impos, icpos;
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
               int pos=getpos(i,j);
               if(grid[i][j]!='#'){
                   //mouse cat 在同一格, cat win
                   q.push(State(pos,pos,0,1));
                   memo[pos][pos][0]=1;
                   q.push(State(pos,pos,1,1));
                   memo[pos][pos][1]=1;
               }
               if(grid[i][j]=='F'){
                   //mouse get here, cat not here, mouse win 
                   for(int k=0;k<m;k++){
                       for(int t=0;t<n;t++){
                           if(k==i && t==j) continue;
                           if(grid[k][t]=='#') continue;
                           int cpos=getpos(k,t);
                           q.push(State(pos,cpos,0,0));
                           memo[pos][cpos][0]=0;
                           q.push(State(pos,cpos,1,0));
                           memo[pos][cpos][1]=0;
                       }
                   }
                   
                   //cat get here, mouse not here, cat win 
                   for(int k=0;k<m;k++){
                       for(int t=0;t<n;t++){
                           if(k==i && t==j) continue;
                           if(grid[k][t]=='#') continue;
                           int mpos=getpos(k,t);
                           q.push(State(mpos,pos,0,1));
                           memo[mpos][pos][0]=1;
                           q.push(State(mpos,pos,1,1));
                           memo[mpos][pos][1]=1;
                       }
                   }
               }
               if(grid[i][j]=='M'){
                   impos=pos;
               }else if(grid[i][j]=='C'){
                   icpos=pos;
               }
            }
        }
        //mouse可以走的情况数  
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(grid[i][j]=='#') continue;
                int mpos=getpos(i,j);
                int deg=1; //原地不动  
                for(int d=0;d<4;d++){
                    for(int step=1;step<=mouseJump;step++){
                        int ni=i+step*dir[d][0];
                        int nj=j+step*dir[d][1];
                        if(ni<0 || ni>=m || nj<0 || nj>=n || grid[ni][nj]=='#') break;
                        deg++;
                    }
                }
                for(int k=0;k<m;k++){
                    for(int t=0;t<n;t++){
                        if(grid[k][t]=='#') continue;
                        int cpos=getpos(k,t);
                        degree[mpos][cpos][0]=deg;
                    }
                }
            }
        }
        // cat可以走的情况数  
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(grid[i][j]=='#') continue;
                int cpos=getpos(i,j);
                int deg=1; //原地不动  
                for(int d=0;d<4;d++){
                    for(int step=1;step<=catJump;step++){
                        int ni=i+step*dir[d][0];
                        int nj=j+step*dir[d][1];
                        if(ni<0 || ni>=m || nj<0 || nj>=n || grid[ni][nj]=='#') break;
                        deg++;
                    }
                }
                for(int k=0;k<m;k++){
                    for(int t=0;t<n;t++){
                        if(grid[k][t]=='#') continue;
                        int mpos=getpos(k,t);
                        degree[mpos][cpos][1]=deg;
                    }
                }
            }
        }
        while(!q.empty()){
            auto cur=q.front();
            q.pop();
            if(cur.mpos==impos && cur.cpos==icpos && cur.turn==0) {
                return cur.win==0? true:false;
            }
            int mx=getx(cur.mpos);
            int my=gety(cur.mpos);
            int cx=getx(cur.cpos);
            int cy=gety(cur.cpos);
            if(cur.turn==0){
                // 上一步cat走  
                //cat原地不动
                if(memo[cur.mpos][cur.cpos][1]==-1){
                    --degree[cur.mpos][cur.cpos][1];
                    if(cur.win==1){
                        q.push(State(cur.mpos,cur.cpos,1,1));
                        memo[cur.mpos][cur.cpos][1]=1;
                    }else{
                        if(degree[cur.mpos][cur.cpos][1]==0){
                            q.push(State(cur.mpos,cur.cpos,1,0));
                            memo[cur.mpos][cur.cpos][1]=0;
                        }
                    }
                }
                //cat 动
                for(int d=0;d<4;d++){
                    for(int step=1;step<=catJump;step++){
                        int ncx=cx+step*dir[d][0];
                        int ncy=cy+step*dir[d][1];
                        int ncpos=getpos(ncx,ncy);
                        if(ncx<0 || ncx>=m || ncy<0 || ncy>=n || grid[ncx][ncy]=='#') break;
                        if(memo[cur.mpos][ncpos][1]!=-1) continue;
                        --degree[cur.mpos][ncpos][1];
                        if(cur.win==1){
                            q.push(State(cur.mpos,ncpos,1,1));
                            memo[cur.mpos][ncpos][1]=1;
                        }else{
                           if(degree[cur.mpos][ncpos][1]==0){
                               q.push(State(cur.mpos,ncpos,1,0));
                               memo[cur.mpos][ncpos][1]=0;
                           }
                        }
                    }
                }
            }else{
                //上一步mouse走  
                //mouse原地不动
                if(memo[cur.mpos][cur.cpos][0]==-1){
                    --degree[cur.mpos][cur.cpos][0];
                    if(cur.win==0){
                        q.push(State(cur.mpos,cur.cpos,0,0));
                        memo[cur.mpos][cur.cpos][0]=0;
                    }else{
                        if(degree[cur.mpos][cur.cpos][0]==0){
                            q.push(State(cur.mpos,cur.cpos,0,1));
                            memo[cur.mpos][cur.cpos][0]=1;
                        }
                    }
                }
                //mouse 动
                for(int d=0;d<4;d++){
                    for(int step=1;step<=mouseJump;step++){
                        int nmx=mx+step*dir[d][0];
                        int nmy=my+step*dir[d][1];
                        int nmpos=getpos(nmx,nmy);
                        if(nmx<0 || nmx>=m || nmy<0 || nmy>=n || grid[nmx][nmy]=='#') break;
                        if(memo[nmpos][cur.cpos][0]!=-1) continue;
                        --degree[nmpos][cur.cpos][0];
                        if(cur.win==0){
                            q.push(State(nmpos,cur.cpos,0,0));
                            memo[nmpos][cur.cpos][0]=0;
                        }else{
                            if(degree[nmpos][cur.cpos][0]==0){
                                q.push(State(nmpos,cur.cpos,0,1));
                                memo[nmpos][cur.cpos][0]=1;
                            }
                        }
                    }
                }
            }
        }
        return false;
    }
    
    int getpos(int i, int j){
        return i*n+j;
    }
    
    int getx(int pos){
        return pos/n;
    }
    
    int gety(int pos){
        return pos%n;
    }
};
原文地址:https://www.cnblogs.com/FEIIEF/p/14292095.html