题意
给定一个迷宫,包括出入口所在列(行、列为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;
}