题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2110
题目描述:
一只小狗在一个古老的迷宫里找到一根骨头,当它叼起骨头时,迷宫开始颤抖,它感觉到地面开始下沉。它才明白骨头是一个陷阱,它拼命地试着逃出迷宫。迷宫是一个N*M大小的长方形,迷宫有一个门。刚开始门是关着的,并且这个门会在第T秒钟开启,门只会开启很短的时间(少于1秒),因此小狗必须恰好在第T秒达到门的位置。每秒钟,它可以向上、下、左或右移动一步到相邻的方格中。但一旦它移动到相邻的方格,这个方格开始下沉,而且会在下1秒消失。所以,它不能在一个方格中停留超过一秒,也不能回到经过的方格。小狗能成功逃离吗?请帮助它。
输入描述:
输入文件中包含多个测试数据。每个测试数据的第1行为3个整数:N、M、T,(1<N、M<7;0<T<50),分别代表迷宫的长和宽,以及迷宫的门会在第T秒时刻开启。
接下来N行信息给出了迷宫的格局,每行有M个字符,这些字符可能为如下值之一。
'X':墙壁,小狗不能进入 'S':小狗所处的位置
'D':迷宫的门 '.':空的方格
输入数据以3个0表示输入数据结束。
输出描述:
对每个测试数据,如果小狗能成功逃离,则输出“YES”,否则输出“NO”
样例输入:
4 4 5
S.X.
..X.
..XD
....
3 4 5
S.X.
..X.
...D
0 0 0
样例输出:
NO
YES
AC代码如下:
import java.util.Scanner;
public class Zoj2110 {
static int t,m,n;
static char[][] map;
static int[][] b;
static int d1[]= {-1,1,0,0};//定义方向
static int d2[]= {0,0,-1,1};
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scanner=new Scanner(System.in);
int x=0,y=0;
while(true)
{
map=new char[64][64]; //每次循环开始都要重新定义
b=new int[64][64];
m=scanner.nextInt();n=scanner.nextInt();t=scanner.nextInt();
if(n==0&&m==0&&t==0) break;
for(int i=0;i<m;i++)
{
String string=scanner.next();
char[] ch=string.toCharArray();
for(int j=0;j<n;j++)
{
map[i][j]=ch[j];
if(map[i][j]=='S')//记录下起点位置
{
x=i;y=j;
b[i][j]=1;
continue;
}
b[i][j]=0;
}
}
if(dfs(x, y, 0)==true)
System.out.println("YES");
else
System.out.println("NO");
}
}
static boolean dfs(int x,int y,int s)
{
int xx,yy;
if(s==t && map[x][y]=='D')return true; //到达终点返回一个true
if(s>=t) return false; //所需时间超过了规定时间就不用继续搜下去了
if(map[x][y]=='D' && s!=t) return false;//到达门但时间不符合要求就返回一个false
for(int i=0;i<4;i++)
{
xx=x+d1[i];
yy=y+d2[i];
if(xx<0 || xx>=m || yy<0 || yy>=n) continue;//向四周搜索
if(b[xx][yy]==0 && map[xx][yy]!='X' )
{
b[xx][yy]=1;
if( dfs(xx,yy,s+1) ) return true;//递归
b[xx][yy]=0;
}
}
return false;
}
}