HDU 3912 Turn Right 题解

题意
给定一个迷宫,包括出入口所在列(行、列为0到R-1,0到C-1,入口所在行是第0行以上,出口所在行是第R-1行以下)、两个格子之间是否有墙,按照能右转就右转,不然再能直走就直走,不然再能左转就左转,不然就后退转身的操作走迷宫,从入口走到出口一次,从出口走到入口一次,问是否走了所有格子至少一遍
思路
记忆化搜索模拟,三个参数当前行,当前列,当前方向,按照题意走
代码
#include <cstdio>
int right[501][501],down[501][501];
bool vis[501][501];
bool st[501][501][4];
int dir[4][2]={-1,0,0,1,1,0,0,-1};
int T,R,C,Ent_Column,Exit_Column;
int tx,ty,f;
void dfs(int x,int y,int d)
{
    if(st[x][y][d])
        return;
    st[x][y][d]=true;
    vis[x][y]=true;
    if(x==tx&&y==ty&&d==f)
        return;
    else if(x+dir[(d+1)%4][0]>=0&&x+dir[(d+1)%4][0]<R&&y+dir[(d+1)%4][1]>=0&&y+dir[(d+1)%4][1]<C&&((d==0&&!right[x][y])||(d==1&&!down[x][y])||(d==2&&!right[x][y-1])||(d==3&&!down[x-1][y])))
        dfs(x+dir[(d+1)%4][0],y+dir[(d+1)%4][1],(d+1)%4);
    else if(x+dir[d][0]>=0&&x+dir[d][0]<R&&y+dir[d][1]>=0&&y+dir[d][1]<C&&((d==0&&!down[x-1][y])||(d==1&&!right[x][y])||(d==2&&!down[x][y])||(d==3&&!right[x][y-1])))
        dfs(x+dir[d][0],y+dir[d][1],d);
    else if(x+dir[(d+3)%4][0]>=0&&x+dir[(d+3)%4][0]<R&&y+dir[(d+3)%4][1]>=0&&y+dir[(d+3)%4][1]<C&&((d==0&&!right[x][y-1])||(d==1&&!down[x-1][y])||(d==2&&!right[x][y])||(d==3&&!down[x][y])))
        dfs(x+dir[(d+3)%4][0],y+dir[(d+3)%4][1],(d+3)%4);
    else dfs(x+dir[(d+2)%4][0],y+dir[(d+2)%4][1],(d+2)%4);
    return;
}
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        bool ans;
        scanf("%d%d%d%d",&R,&C,&Ent_Column,&Exit_Column);
        for(int i=0;i<2*R-1;i++)
            if(i%2==0)
                for(int j=0;j<C-1;j++)
                    scanf("%d",&right[i/2][j]);
            else for(int j=0;j<C;j++)
                scanf("%d",&down[i/2][j]);
        tx=R-1;
        ty=Exit_Column;
        f=1;
        dfs(0,Ent_Column,2);
        tx=0;
        ty=Ent_Column;
        f=3;
        dfs(R-1,Exit_Column,0);
        ans=true;
        for(int i=0;i<R&&ans;i++)
            for(int j=0;j<C&&ans;j++)
                if(!vis[i][j])
                    ans=false;
        if(ans)
            printf("YES\n");
        else printf("NO\n");
        for(int i=0;i<R;i++)
            for(int j=0;j<C;j++)
                vis[i][j]=false;
        for(int i=0;i<R;i++)
            for(int j=0;j<C;j++)
                for(int k=0;k<4;k++)
                    st[i][j][k]=false;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值