首先,该题很明显要使用递归来计算,为了是算法更有效,使用剪枝函数。
(1)若已剩的步数小于两点之间x的间距和y的间距之和,则不可能达到,该点可以减去。
(2)因为奇数点(x+y为奇数)到奇数点,偶数点到偶数点的步数为偶数,奇数到偶数的步数为奇数,则可以利用这个判断起点到终点是否可达。
import java.util.Scanner; public class Main_1010 { static char[][] status; static boolean[][] flag; static int T,N,M,x2,y2; static boolean success; public static void main(String[] args) { Scanner in = new Scanner(System.in); N = in.nextInt(); M = in.nextInt(); T = in.nextInt(); in.nextLine(); int x = 0, y =0; while(N != 0 && M !=0 && T !=0){ status = new char[N][M]; flag = new boolean[N][M]; success = false; for(int i = 0; i < N; i++){ String s = in.nextLine(); for(int j = 0; j < M; j++){ status[i][j] = s.charAt(j); if(status[i][j] == 'S'){ x = i; y = j; } if(status[i][j] == 'D'){ x2 = i; y2 = j; } } } visit(x,y,0); if(success){ System.out.println("YES"); }else{ System.out.println("NO"); } N = in.nextInt(); M = in.nextInt(); T = in.nextInt(); in.nextLine(); } } public static void visit(int x,int y,int count){ if(count > T){ return; } //判断当前剩下步数是否足够 if((T-count) < Math.abs(x2-x)+Math.abs(y2-y)){ return; } //奇偶剪枝 if((T-count)%2 +(x+y+x2+y2)%2 ==1){ return; } if(status[x][y] == 'D' && count == T){ success = true; return; } if(status[x][y] == '.' || status[x][y] == 'S'){ flag[x][y] = true; //向上走 if(x - 1 >= 0 && !flag[x-1][y]){ visit(x-1,y,count+1); } //向下走 if(x + 1 < N && !flag[x+1][y]){ visit(x+1,y,count+1); } //向左走 if(y -1 >= 0 && !flag[x][y-1]){ visit(x,y-1,count+1); } //向右走 if(y + 1 < M && !flag[x][y+1]){ visit(x,y+1,count+1); } flag[x][y] = false; } } }
特别注意的是,每次全局变量都需要重新初始化,而且success只有在到达D时才变为true,当不满足时不用改变,因为达到D后,函数还是要完成之前压栈的函数,之后的值会覆盖原来的success值。
参考 https://blog.csdn.net/u014174811/article/details/41293209