HDU1010 --- Tempter of the Bone(dfs+剪枝)

时间:2023-03-09 19:52:34
HDU1010 --- Tempter of the Bone(dfs+剪枝)

小明做了一个很久很久的梦,醒来后他竟发现自己和朋友在一个摇摇欲坠的大棋盘上,他们必须得想尽一切办法逃离这里。
经过长时间的打探,小明发现,自己所在的棋盘格子上有个机关,上面写着“你只有一次机会,出发后t秒大门会为你敞开”,而他自己所在的棋盘是大小为 N*M 的长方形,他可以向上下左右四个方向移动(不可走有障碍点)。棋盘中有一扇门。根据机关的提示,小明顿时明白了,他和朋友必须在第 t 秒到门口。而这一切,没有回头路!因为一旦他移动了,他刚才所在的点就会消失,并且他不能在一个点上停留超过一秒,不然格子会爆炸。大逃亡开始了,请问小明和朋友能安全的逃出这奇怪的棋盘吗?

Input

输入多组测试数据。每个测试用例的第一行包含三个整数 N、M 和 T ( 1 < N , M < 7 ; 0 < T < 50 ),分别表示棋盘的大小和门打开的时间。接下来的N行给出棋盘布局,每一行包含M个字符。其中
".": 无障碍点
"X": 障碍点
"S": 起点
"D": 门

输入以 3 个 0 结束。这个测试用例不需要处理。

Output

对于每组样例输出一行。
如果小明能够安全逃出,输出 "YES" ,否则输出 "NO"。

Sample Input

4 4 5
S.X.
..X.
..XD
....
3 4 5
S.X.
..X.
...D
0 0 0

Sample Output

NO
YES 代码:
import java.util.Arrays;
import java.util.Scanner; public class Main{
static int n,m,T;
static final int N=10;
static int sx,sy,ex,ey;
static int dx[]={0,0,1,-1};
static int dy[]={1,-1,0,0};
static char map[][]=new char[N][N];
static boolean vis[][]=new boolean[N][N];
static boolean flag; static void dfs(int x,int y,int t){
          //这种多if判断的一定加上return
if(flag) return; //已经找到一种走法
if(t>T) return; //大于要求的时间
if(T-t-Math.abs(x-ex)-Math.abs(y-ey)<0) return; //剩余的步数不足以到达终点
if((T-t)%2!=(Math.abs(x-ex)+Math.abs(y-ey))%2) return; //奇偶性一致
if(t==T && x==ex && y==ey){
flag=true;
} for(int i=0;i<4;i++){
int xx=x+dx[i];
int yy=y+dy[i];
if(xx<0 || yy<0 || xx>=n || yy>=m ||vis[xx][yy]) continue;
vis[xx][yy]=true;
dfs(xx,yy,t+1);
vis[xx][yy]=false;
}
}
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
while(scan.hasNext()){
n=scan.nextInt();
m=scan.nextInt();
T=scan.nextInt();
if(n==0 && m==0 &&T==0) break;
for(int i=0;i<n;i++) map[i]=scan.next().toCharArray();
for(int i=0;i<N;i++) Arrays.fill(vis[i],false);
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(map[i][j]=='S'){
sx=i; sy=j;
}
else if(map[i][j]=='D'){
ex=i; ey=j;
}
else if(map[i][j]=='X')
vis[i][j]=true;
vis[sx][sy]=true;
flag=false;
dfs(sx,sy,0);
if(flag) System.out.println("YES");
else System.out.println("NO");
}
}
}