import java.util.Scanner;
public class C1010 {
static int m,n,time;
static boolean vis[][];
static char map[][];
static int dir[][] = {{-1,0},{1,0},{0,-1},{0,1}};
static int start_x,start_y,end_x,end_y;
static boolean flag = false;
public static void main(String args[]) {
Scanner scan = new Scanner(System.in);
while(scan.hasNext()) {
m = scan.nextInt();n = scan.nextInt();time = scan.nextInt();
if(m==0&&n==0&&time==0)break;
vis = new boolean[m+100][n+1000];map = new char[m][n];
for(int i=0;i<m;i++) {
String str = scan.next();
map[i] = str.toCharArray();
for(int j=0;j<n;j++) {
if(map[i][j]=='S') {start_x = i; start_y = j;}
if(map[i][j]=='D') {end_x = i; end_y = j;}
vis[i][j] = false;
}
}//读取完毕
flag = false;
dfs(start_x,start_y,0);
System.out.println(flag+" 完成");
}
}
public static void dfs(int x,int y,int step) {
if(map[x][y]=='D') {//出口
if(step == time) { flag = true;}
return;
}
if(step>time) return;
//接下来两端为两个重要的剪枝过程,如果直线距离大于所剩步数 那么说明不能达到
int tmp = time - step - abs(end_x-x) - abs(end_y-y);
if(tmp < 0 ||tmp%2!=0) {return;}//奇偶剪枝
for(int k=0;k<=3;k++) {
int xx = x+dir[k][0];
int yy = y+dir[k][1];
if(xx>=0&&xx<m&&yy>=0&&yy<n&&map[xx][yy]!='X'&&!vis[xx][yy]){
vis[xx][yy] = true;
dfs(xx,yy,step+1);
if(flag) return;//提前剪枝 要不然超时
vis[xx][yy] = false;
}
}
}
static int abs(int a) {
if(a>=0)return a;
return -a;
}
}
上次就想用把结点带入dfs的方法写…结果…我现在终于学会了m×n行的读入方式!!!!!!!原来next只能读成一行一的!!!!!
关于奇偶剪枝:无论是怎么走,我们的步数肯定比最短路径数多一个偶数(按最短路径+往返1个格子的程度正好多2)
如果题目中输入的步数比最短路径数多得是一个奇数,那么我们永远也不可能走到,所以直接输出NO;