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;
}
};