左手定则

左手定则

Time Limit: 1000ms
Memory Limit: 65536KB
64-bit integer IO format:  %lld      Java class name:  Main

玩过RPG(尤其是国产RPG)的童鞋都应该对迷宫这种神棍的设定深恶痛绝,尤其是当你转了半小时之后发现回到了原地,这种感觉真是无比的痛苦。。。万一游戏还中途崩溃了那真是连掀桌子、砸键盘、摔鼠标的心都有了⋯⋯
经过无数次的TRIAL AND ERROR之后,51isoft终于下定决心认定迷宫存在的意义就是延长游戏时间,SO,他决定借鉴著名的左手定则(就是在每一个路口,我们都选择最左边的方向,左转的优先级最高,其次为向前,最后为右转,如果实在走进了一个死胡同,那就连续右转两次,回头向后走。稍微研究一下这种走迷宫的方法,我们就发现在这个过程中,事实上我们的左手可以始终放在墙上。)对迷宫进行探索。
但是呢,左手定则并不能保证遍历到迷宫中的每一个点。悲剧的是,某项重要的通关道具被放在了这个迷宫中⋯⋯幸运的是,游戏迷宫的地图可以绘制出来,现在51isoft请求你的帮助。对于一个给定的地图,他想知道是不是能够通过左手定则取得这件道具。

Input

多组数据,以EOF结尾。

对于每组数据,第一行有两个整数N,M代表接下来有n行字符串,每行m个字符,其中0<n<=100,0<m<=100,表示一个n×m的迷宫。
其中‘#’表示墙,‘S’表示起点,‘T’表示道具,‘.’表示空地。

接下来是一个方向(NSWE),表示起始面向的方向。

数据保证最外一圈都是墙。

Output

对于每组数据输出一行。‘YES’表示可以到达,‘NO’表示无法到达。

Sample Input

8 10
##########
#...T....#
#.####...#
#.#..#.#.#
#.#....#.#
#.####.#.#
#......#S#
##########
N

8 10
##########
#........#
#.####...#
#.#T.#.#.#
#.#....#.#
#.####.#.#
#......#S#
##########
N

Sample Output

YES
NO

Hint

E东

S南

W西

N北

 

#include<stdio.h>
#include<string.h>
char a[105][105];
int vis[4][105][105],n,m;
int sx,sy,ex,ey;
int step[4][4][2]= {{0,-1,-1,0,0,1,1,0},{-1,0,0,1,1,0,0,-1},{0,1,1,0,0,-1,-1,0},{1,0,0,-1,-1,0,0,1}};
bool judge(int nextx,int nexty)
{
if(nextx>=0&&nextx<n&&nexty>=0&&nexty<m&&a[nextx][nexty]!='#')
return true;
return false;
}
bool dfs(int nowx,int nowy,int nowdir)
{
if(nowx==ex&&nowy==ey)
return true;
for(int i=0; i<4; i++)
{
int nextx=nowx+step[nowdir][i][0];
int nexty=nowy+step[nowdir][i][1];
if(judge(nextx,nexty))
{
int temp ;
if(step[nowdir][i][0]==1)
temp =0;
else if(step[nowdir][i][0]==-1)
temp =1;
else if(step[nowdir][i][1]==1)
temp =2;
else
temp =3;
if(vis[temp][nextx][nexty]==1)
return false ;
if(a[nextx][nexty]=='T')
return true;
if(vis[temp][nextx][nexty]==0)
{
vis[temp][nextx][nexty]=1;
return dfs(nextx,nexty,(i+3+4-4+nowdir)%4);
}
}
}
return false;
}
char s[2];
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
sx = sy =0;
ex = ey = -1;
for(int i=0; i<n; i++)
scanf("%s",a[i]);
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
{
if(a[i][j]=='T')
{
ex=i;
ey=j;
}
if(a[i][j]=='S')
{
sx = i;
sy = j;
}
}
scanf("%s",s);
int nowdri ;
if(s[0]=='N')
nowdri=0;
else if(s[0]=='E')
nowdri=1;
else if(s[0]=='S')
nowdri = 2;
else if(s[0]=='W')
nowdri=3;
memset(vis,0,sizeof(vis));
if(dfs(sx,sy,nowdri))
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
不会原地转圈

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值