思路:
小狗走n * m迷宫,从S位置到E位置,时间要正好为T, 每秒走一步,可以向上下左右四个方向走。
DFS + 剪枝:
1、当前位置[x, y],当前所用时间k, 到终点[ex, ey]的最短步数是abs(ex-x) + abs(ey-y) + k > T 则不需继续了
2、奇偶剪枝:参考博客
代码:
import java.util.HashSet; import java.util.Scanner; import java.util.Set; public class Main{ public static int n, m, t; public static boolean ans; public static String map[]; public static int vis[][]; public static int dir[][] = {{-1,0},{1,0},{0,-1},{0,1}}; public static int s[] = new int[2]; public static int e[] = new int[2]; public static void main(String[] args) { Scanner in = new Scanner(System.in); while(in.hasNext()){ n = in.nextInt(); m = in.nextInt(); t = in.nextInt(); if(n == 0 && m == 0 && t == 0) break; in.nextLine(); map = new String[n]; vis = new int[n][m]; for(int i = 0; i < n; i++){ map[i] = in.nextLine(); for(int j = 0; j < m; j++){ if(map[i].charAt(j) == 'S'){ s[0] = i; s[1] = j; //起始点 } else if(map[i].charAt(j) == 'D'){ e[0] = i; e[1] = j; //终点 } } } ans = false; vis[s[0]][s[1]] = 1; dfs(s[0],s[1],0); System.out.println(ans ? "YES" : "NO"); } } private static void dfs(int x, int y, int k) { // System.out.println(x + " " + y + " " + k); if(x == e[0] && y == e[1] && k == t){ ans = true; return ; } int step = Math.abs(e[0] - x) + Math.abs(e[1] - y); if(step + k > t) return; if(step % 2 != (t - k) % 2) return ; for(int i = 0; i < 4; i++){ int x1 = x + dir[i][0]; int y1 = y + dir[i][1]; if(check(x1, y1)){ vis[x1][y1] = 1; dfs(x1, y1, k+1); if(ans) return ; vis[x1][y1] = 0; } } } private static boolean check(int x, int y) { if(x < 0 || x >= n || y < 0 || y >= m) return false; if(map[x].charAt(y) == 'X' || vis[x][y] == 1) return false; return true; } }