Description
500年前,Jesse是我国最卓越的剑客。他英俊潇洒,而且机智过人^_^。
突然有一天,Jesse心爱的公主被魔王困在了一个巨大的迷宫中。
Jesse听说这个消息已经是两天以后了,他急忙赶到迷宫,开始到处寻找公主的下落。
令人头痛的是,Jesse是个没什么方向感的人,因此,他在行走过程中,不能转太多弯了,否则他会晕倒的。 我们假定Jesse和公主所在的位置都是空地,
初始时,Jesse所面向的方向未定,他可以选择4个方向的任何一个出发,而不算成一次转弯。
希望你帮他判断一下他是否有机会找到心爱的公主。
Input
题目包括多组测试数据.
第1行为一个整数T(1 ≤ T≤ 100),表示测试数据的个数,接下来为T组测试数据.
每组测试数据以两个整数N,M,K(1<=N, M≤100, 0<K<=10)开头,
分别代表迷宫的高,长和Jesse最多能转的弯数,
(紧接着有N行,M列字符,由".","*","P","S"组成。其中
"." 代表能够行走的空地。
"*" 代表墙壁,Jesse不能从此通过。
"P" 是公主所在的位置。
"S" 是Jesse的起始位置。
每个时间段里Jesse只能选择“上、下、左、右”任意一方向走一步。
Output
如果Jesse能在晕之前找到公主,输出“YES”,否则输出“NO”。
Sample Input
2
5 5 1
P..**
*.**.
S....
.....
*....
5 5 2
P..**
*.**.
S....
.....
*....
Sample Output
NO
YES
使用vis数组来标记走过的路,可以避免走重复的路,使用cD来记录转弯的次数。对于转弯方向的判断,可以利用变量direction,和i,i有四种值,分别为0,1,2,3表示四个不同的方向。
#include<cstdio>
char map[101][101];
using namespace std;
int dx[4]= {0,0,-1,1};
int dy[4]= {1,-1,0,0};
int vis[101][101];
int cD;//表示改变方向的次数
int N,M,K;
int test;//测试数据的组数
bool find;
void init() {//做一些初始化的工作
for(int i=0; i<101; i++) {
for(int j=0; j<101; j++) {
vis[i][j]=0;
}
}
find=false;
cD=-1;
}
void dfs(int x,int y,int direction) {//这里假定对每一个被调用的x和y,都不超过边界。
if(!vis[x][y]) {
vis[x][y]=1;
if(map[x][y]=='*') return;
if(find) return;
if(cD>K) return;
if(map[x][y]=='P') {
find=true;
return;
}
for(int i=0; i<4; i++) {
if(x+dx[i]<0||x+dx[i]>=N || y+dy[i]<0||y+dy[i]>=M) return;
if(i!=direction) {
cD++;//将改变方向的数目加一
dfs(x+dx[i],y+dy[i],i);
cD--;//回溯,将改变方向的次数减一
}
dfs(x+dx[i],y+dy[i],i);
}
vis[x][y]=0;
}
}
int main() {
freopen("in.txt","r",stdin);
scanf("%d",&test);
while(test--) {
init();
scanf("%d%d%d",&N,&M,&K);
getchar();
for(int i=0; i<N; i++) {
for(int j=0; j<M; j++) {
scanf("%c",&map[i][j]);
}
getchar();
}
for(int i=0; i<N; i++) {
for(int j=0; j<M; j++) {
if(map[i][j]=='S') {
dfs(i,j,-1);
i=N;//可以快速跳出循环
}
}
}
if(find) {
printf("YES\n");
} else {
printf("NO\n");
}
}
return 0;
}