题目描述
题目描述
Alice and Bob are playing a game on an n×m grid where each cell has either ‘A’, ‘B’ or ‘.’ written on it. They take turns moving a chess piece on the grid and Alice moves first.
Initially the piece is on cell (1,1). In each player’s turn, he or she can move the piece one cell right or one cell down. That is, if the piece is on cell (x,y)before the turn, the player can move it to (x+1,y) or (x,y+1), as long as it doesn’t go beyond the grid.
At any time, if the piece is on a cell with ‘A’, Alice wins and the game ends. If the piece is on a cell with ‘B’, Bob wins and the game ends. If the piece reaches cell (n,m) without the game ending, then it is a draw.
Since Alice cannot decide what acts Bob will take, she would like to know if she can be in control of the situation. Given the grid they’re playing on, can you tell her if she can always find a way to win, draw or lose the game no matter what acts Bob takes?
简单翻译
~~~~~~ 题意就是Alice和Bob在一个n* m的网格上博弈,Alice先手,碰上’A’就Alice赢,碰到’B’就Bob赢,如果走到最右下角的格 (n,m),如果游戏还没结束就平手,从(1,1)开始走,每次只能向右或向下走,问是否无论Bob怎么走Alice总有一个方式让他自己赢,平或输
题目解析
~~~~~~ 这道题有个网格在这,肯定不能像一些博弈题一样直接用思维去想直接找出策略,所以我们要使用博弈DP,博弈状态就是f[i][j],代表走到这先手是否总有一种方法让他赢,平或输,思考第一种让他赢得方式,边界就是走到A的地方就必定有,走到B的地方就必定没有,走到(n,m)也必定没有,其他时候如果Alice走,向右或向下有只要有一个地方有必赢方案,这里的状态也为有必赢方案,若Bob走,只有当向下和向右走都有必赢方案是此状态才有必赢方案,其他两种与之类似,只需要将边界变换一下
代码
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=510;
int f[N][N];
char s[N][N];
int n,m;
int dfs1(int x,int y)
{
if(f[x][y]!=-1)return f[x][y];
if(s[x][y]=='B')return f[x][y]=0;
if(s[x][y]=='A')return f[x][y]=1;
if(x==n&&y==m)return f[x][y]=0;
if((x+y)%2==0)
{
if(x==n)return f[x][y]=dfs1(x,y+1);
else if(y==m)return f[x][y]=dfs1(x+1,y);
else return f[x][y]=(dfs1(x+1,y)||dfs1(x,y+1));
}
else
{
if(x==n)return f[x][y]=dfs1(x,y+1);
else if(y==m)return f[x][y]=dfs1(x+1,y);
else return f[x][y]=(dfs1(x+1,y)&&dfs1(x,y+1));
}
}
int dfs2(int x,int y)
{
if(f[x][y]!=-1)return f[x][y];
if(s[x][y]=='B')return f[x][y]=0;
if(s[x][y]=='A')return f[x][y]=0;
if(x==n&&y==m)return f[x][y]=1;
if((x+y)%2==0)
{
if(x==n)return f[x][y]=dfs2(x,y+1);
else if(y==m)return f[x][y]=dfs2(x+1,y);
else return f[x][y]=(dfs2(x+1,y)||dfs2(x,y+1));
}
else
{
if(x==n)return f[x][y]=dfs2(x,y+1);
else if(y==m)return f[x][y]=dfs2(x+1,y);
else return f[x][y]=(dfs2(x+1,y)&&dfs2(x,y+1));
}
}
int dfs3(int x,int y)
{
if(f[x][y]!=-1)return f[x][y];
if(s[x][y]=='B')return f[x][y]=1;
if(s[x][y]=='A')return f[x][y]=0;
if(x==n&&y==m)return f[x][y]=0;
if((x+y)%2==0)
{
if(x==n)return f[x][y]=dfs3(x,y+1);
else if(y==m)return f[x][y]=dfs3(x+1,y);
else return f[x][y]=(dfs3(x+1,y)|dfs3(x,y+1));
}
else
{
if(x==n)return f[x][y]=dfs3(x,y+1);
else if(y==m)return f[x][y]=dfs3(x+1,y);
else return f[x][y]=(dfs3(x+1,y)&dfs3(x,y+1));
}
}
int main()
{
int T;
cin>>T;
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%s",s[i]+1);
memset(f,-1,sizeof(f));
dfs1(1,1);
if(f[1][1]==1)cout<<"yes"<<' ';
else cout<<"no"<<' ';
memset(f,-1,sizeof(f));
dfs2(1,1);
if(f[1][1]==1)cout<<"yes"<<' ';
else cout<<"no"<<' ';
memset(f,-1,sizeof(f));
dfs3(1,1);
if(f[1][1]==1)cout<<"yes"<<' ';
else cout<<"no"<<' ';
puts("");
}
return 0;
}