| 马踏棋盘算法也被称为骑士周游问题 |
| 将马随机放在国际象棋的8×8棋盘Board[0~7][0~7]的某个方格中,马按走棋规则(马走日字)进行移动。要求每个方格只进入一次,走遍棋盘上全部64个方格 |

| 1. 创建棋盘 chessBoard , 是一个二维数组 |
| 2. 将当前位置设置为已经访问,然后根据当前位置,计算马儿还能走哪些位置,并放入到一个集合中(ArrayList), 最多有8个位置, 每走一步,就使用step+1 |
| 3. 遍历ArrayList中存放的所有位置,看看哪个可以走通 , 如果走通,就继续,走不通,就回溯. |
| 4. 判断马儿是否完成了任务,使用 step 和应该走的步数比较 , 如果没有达到数量,则表示没有完成任务,将整个棋盘置0 |
| |
| 注意:马儿不同的走法(策略),会得到不同的结果,效率也会有影响(优化) |
| |
| |
| Point p1 = new Point() |
| if((p1.x = curPoint.x - 2) >= 0 && (p1.y = curPoint.y -1) >= 0) { |
| ps.add(new Point(p1)) |
| } |
| public class HorseChessboard { |
| |
| public static void main(String[] args) { |
| System.out.println("骑士周游算法,开始运行~~"); |
| |
| X = 8; |
| Y = 8; |
| int row = 1; |
| int column = 1; |
| |
| int[][] chessboard = new int[X][Y]; |
| visited = new boolean[X * Y]; |
| |
| long start = System.currentTimeMillis(); |
| traversalChessboard(chessboard, row - 1, column - 1, 1); |
| long end = System.currentTimeMillis(); |
| System.out.println("共耗时: " + (end - start) + " 毫秒"); |
| |
| |
| for(int[] rows : chessboard) { |
| for(int step: rows) { |
| System.out.print(step + "\t"); |
| } |
| System.out.println(); |
| } |
| } |
| |
| private static int X; |
| private static int Y; |
| |
| private static boolean visited[]; |
| |
| private static boolean finished; |
| |
| |
| |
| |
| |
| |
| |
| |
| public static void traversalChessboard(int[][] chessboard, int row, int column, int step) { |
| chessboard[row][column] = step; |
| |
| visited[row * X + column] = true; |
| |
| ArrayList<Point> ps = next(new Point(column, row)); |
| |
| while(!ps.isEmpty()) { |
| Point p = ps.remove(0); |
| |
| if(!visited[p.y * X + p.x]) { |
| traversalChessboard(chessboard, p.y, p.x, step + 1); |
| } |
| } |
| |
| |
| |
| |
| |
| if(step < X * Y && !finished ) { |
| chessboard[row][column] = 0; |
| visited[row * X + column] = false; |
| } else { |
| finished = true; |
| } |
| } |
| |
| |
| |
| |
| |
| |
| public static ArrayList<Point> next(Point curPoint) { |
| |
| ArrayList<Point> ps = new ArrayList<Point>(); |
| |
| Point p1 = new Point(); |
| |
| if((p1.x = curPoint.x - 2) >= 0 && (p1.y = curPoint.y -1) >= 0) { |
| ps.add(new Point(p1)); |
| } |
| |
| if((p1.x = curPoint.x - 1) >=0 && (p1.y=curPoint.y-2)>=0) { |
| ps.add(new Point(p1)); |
| } |
| |
| if ((p1.x = curPoint.x + 1) < X && (p1.y = curPoint.y - 2) >= 0) { |
| ps.add(new Point(p1)); |
| } |
| |
| if ((p1.x = curPoint.x + 2) < X && (p1.y = curPoint.y - 1) >= 0) { |
| ps.add(new Point(p1)); |
| } |
| |
| if ((p1.x = curPoint.x + 2) < X && (p1.y = curPoint.y + 1) < Y) { |
| ps.add(new Point(p1)); |
| } |
| |
| if ((p1.x = curPoint.x + 1) < X && (p1.y = curPoint.y + 2) < Y) { |
| ps.add(new Point(p1)); |
| } |
| |
| if ((p1.x = curPoint.x - 1) >= 0 && (p1.y = curPoint.y + 2) < Y) { |
| ps.add(new Point(p1)); |
| } |
| |
| if ((p1.x = curPoint.x - 2) >= 0 && (p1.y = curPoint.y + 1) < Y) { |
| ps.add(new Point(p1)); |
| } |
| return ps; |
| } |
| |
| } |
| 1. 我们获取当前位置,可以走的下一个位置的集合 |
| |
| ArrayList<Point> ps = next(new Point(column, row)); |
| 2. 我们需要对 ps 中所有的Point 的下一步的所有集合的数目,进行非递减排序,就ok , |
| 9, 7, 6, 5, 3, 2 , 1 |
| 1, 2, 3, 4,5,6, 10, |
| |
| 1, 2, 2, 2, 3,3, 4, 5, 6 |
| 9, 7, 6,6, 6, 5,5, 3, 2 , 1 |
| |
| sort(ps); |
| |
| |
| public static void sort(ArrayList<Point> ps) { |
| ps.sort(new Comparator<Point>() { |
| @Override |
| public int compare(Point o1, Point o2) { |
| |
| |
| int count1 = next(o1).size(); |
| |
| int count2 = next(o2).size(); |
| if(count1 < count2) { |
| return -1; |
| } else if (count1 == count2) { |
| return 0; |
| } else { |
| return 1; |
| } |
| } |
| |
| }); |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南