“蔚来杯“2022牛客暑期多校训练营6 Z-Game on grid

题目描述

题目描述
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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值