做题感悟:这题开始时没想出来什么好办法,但是某个瞬间灵感爆发想到用方向做第三维标记这样就很轻松解决了。
解题思路:用方向做第三维标记看是否重复走,只要发现重复走就结束。
代码:
#include<stdio.h>
#include<iostream>
#include<map>
#include<stack>
#include<string>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std ;
const double PI = 3.1415926 ;
const int INF = 99999999 ;
const int MX =106 ;
int n,m,ans ;
char s[MX][MX] ;
bool vis[MX][MX][8] ;
int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1} ; // 下 0 上 1 右 2 左 3
int d[8][8]={{1,2,0,3},{0,3,1,2},{2,0,3,1},{3,1,2,0}} ; // 初始方向--->东 0 西 1 南 2 北 3
int dz[8][10]={{3,0,2,1},{2,1,3,0},{0,2,1,3},{1,3,0,2}} ;// 标明下一个方向
bool search(int x,int y)
{
if(x<0||y<0||x>=n||y>=m||s[x][y]=='#')
return false ;
return true ;
}
void dfs(int x,int y,int cnt)
{
if(ans) return ;// 已经知道结果
if(s[x][y]=='T')
{
ans=1 ;
return ;
}
bool flag=false ;
for(int i=0 ;i<4 ;i++)
{
int rx=d[cnt][i] ;
int sx=x+dx[rx] ;
int sy=y+dy[rx] ;
if(search(sx,sy)&&!flag)
{
int kt=dz[cnt][i] ;
if(!vis[sx][sy][kt])
{
flag=true ; // 走成一个方向则余下的可走方向都不用走了
vis[sx][sy][kt]=true ;
dfs(sx,sy,kt) ;
}
else ans=2 ; // 走了重复路,说明不可能找到
}
}
}
int main()
{
char ch ;
int x,sx,sy ;
while(~scanf("%d%d",&n,&m))
{
for(int i=0 ;i<n ;i++)
{
scanf("%s",s[i]) ;
for(int j=0 ;j<m ;j++)
if(s[i][j]=='S')
{
sx=i ;
sy=j ;
}
}
cin>>ch ;
if(ch=='E')
x=0 ;
else if(ch=='W')
x=1 ;
else if(ch=='S')
x=2 ;
else x=3 ;
ans=0 ;
memset(vis,false,sizeof(vis)) ;
dfs(sx,sy,x) ;
printf("%s\n",ans==1 ? "YES" : "NO") ;
}
return 0 ;
}