问题描述
一个8×8的棋盘上有一个马初始位置为(a,b),他想跳到(c,d),问是否可以?如果可以,最少要跳几步?
输入格式:
一行四个数字a,b,c,d。
输出格式:
如果跳不到,输出-1;否则输出最少跳到的步数。
样例输入:
1 1 2 3
样例输出:
1
数据规模和约定:
0思路:
用深度优先遍历(DFS)搜索每一种可能到达的情况。
我们熟知马在象棋中只能走“日”,因此:
对于当前坐标x、y的变化共有8种情况:(1,2)(1,-2)(-1,-2)(-1,2)(2,-1)(2,1)(-2,-1)(-2,1)完整代码:
import java.util.Scanner; public class Main { static int c,d; // 对于不变的数据可以定义为全局变量,便于访问 static int[] dx = new int[]{1,1,-1,-1,2,2,-2,-2}; // 8种状态 static int[] dy = new int[]{2,-2,2,-2,1,-1,1,-1}; static boolean[][] visit = new boolean[9][9]; // 用来判断当前坐标是否访问过 static int step = 64; // 最大步数不可能超过64 public static void main(String[] args) { Scanner sc = new Scanner(System.in); int a = sc.nextInt(); int b = sc.nextInt(); c = sc.nextInt(); d = sc.nextInt(); solve(a,b,0); step = step==64?-1:step; // 若step为发生改变,则没有方案到达,应输出-1; System.out.println(step); } private static void solve(int a, int b, int st) { if (a<=0||a>8||b<=0||b>8||visit[a][b]||st>=step) return; // 若越界或者已访问过,则返回;当前步数若已大于已找到的步数,则返回,减少工作量 if (a==c&&b==d){ step = Math.min(step,st); //满足要求时,返回当前步数和已找到方案的步数的较小值 return; } visit[a][b]=true; // 访问了的坐标标记为true for (int i=0;i<8;i++){ solve(a+dx[i],b+dy[i],st+1); // DFS } visit[a][b]=false; // 回溯 } }



