摘要:骑士周游问题又叫马踏棋盘问题未优化前没有策略定义棋盘的行数和列数定义棋盘上的某个点是否被访问过记录是否周游结束从第一行第一列开始走,第一次走算第一步,即展示下是棋盘,
骑士周游问题又叫马踏棋盘问题
public class Main { //定义棋盘的行数和列数 static int X = 8; static int Y = 8; //定义棋盘上的某个点是否被访问过 static boolean[] isVisited; //记录是否周游结束 static boolean isFinished = false; public static void main(String[] args) { isVisited = new boolean[X * Y]; int[][] chessBoard = new int[X][Y]; //从第一行第一列开始走,第一次走算第一步,即step=1 travelChessboard(chessBoard,0,0,1); //展示下chessBoard for (int[] row: chessBoard){ for (int step: row){ System.out.print(step + " "); } System.out.println(); } } /** * * @param chessBoard 是棋盘,因为递归,所以在不断变化 * @param row 是马所在的行,也就是y值 * @param column 是马所在的列,也就是x值 * @param step 马走到的第几步 */ public static void travelChessboard(int[][] chessBoard,int row,int column,int step){ //假定这一点是可以走的,所以设置已访问,步数也得加上 chessBoard[row][column] = step;//假定可以走,所以先走过去看看,设置走过去的步数 isVisited[row * X + column] = true;//假定可以走,所以先走过去看看,设置成已访问 //得到下一步可以走的点的集合 ArrayList<Point> nextPoints = getNext(new Point(column, row)); while (!nextPoints.isEmpty()){ //首先取出一个来 Point nextPoint = nextPoints.remove(0); //如果这个点没有被访问过 if (!isVisited[nextPoint.y * X + nextPoint.x]){ travelChessboard(chessBoard,nextPoint.y,nextPoint.x,step + 1);//这里我一开始写了step++ 其实应该是step+1 } } //如果假定失败,其实这个点是不可以走的,那么我们就进行回溯!!! if (step < X * Y && !isFinished){ chessBoard[row][column] = 0; isVisited[row * X + column] = false; }else { isFinished = true; } } /** * 传入当前点,得到能走的下一个点的集合 * @param curPoint * @return */ public static ArrayList<Point> getNext(Point curPoint){ //创建结果集 ArrayList<Point> nextPoints = new ArrayList<>(); Point nextPoint = new Point(); //可以走0 if ((nextPoint.x = curPoint.x + 2) < X && (nextPoint.y = curPoint.y - 1) >= 0){ nextPoints.add(new Point(nextPoint)); } //表示马可以走1 if ((nextPoint.x = curPoint.x + 2) < X && (nextPoint.y = curPoint.y + 1) < Y){ nextPoints.add(new Point(nextPoint)); } //可以走2 if ((nextPoint.x = curPoint.x + 1) < X && (nextPoint.y = curPoint.y + 2) < Y){ nextPoints.add(new Point(nextPoint)); } //可以走3 if ((nextPoint.x = curPoint.x - 1) >= 0 && (nextPoint.y = curPoint.y + 2) < Y){ nextPoints.add(new Point(nextPoint)); } //可以走4 if ((nextPoint.x = curPoint.x - 2) >= 0 && (nextPoint.y = curPoint.y + 1) < Y){ nextPoints.add(new Point(nextPoint)); } //可以走5 if ((nextPoint.x = curPoint.x - 2) >= 0 && (nextPoint.y = curPoint.y - 1) >= 0){ nextPoints.add(new Point(nextPoint)); } //可以走6 if ((nextPoint.x = curPoint.x - 1) >= 0 && (nextPoint.y = curPoint.y - 2) >= 0){ nextPoints.add(new Point(nextPoint)); } //可以走7 if ((nextPoint.x = curPoint.x + 1) < X && (nextPoint.y = curPoint.y - 2) >= 0){ nextPoints.add(new Point(nextPoint)); } return nextPoints; }}
结果略去,等结果时间太长了
主要是添加了这个方法
添加了这个方法后,可以减少回溯的次数,极大的提高效率
public static void getNextNext(ArrayList<Point> arrayList){ //重写集合的sort方法,将其按下一步可选点数目由小到大的顺序排列,再准确一点就是非递减排序(因为有相同点) arrayList.sort(new Comparator<Point>() { @Override public int compare(Point o1, Point o2) { //得到o1的下一步可选点的数目 int count1 = getNext(o1).size(); //得到o2的下一步可选点的数目 int count2 = getNext(o2).size(); if (count1 > count2){ return -1; }else if (count1 == count2){ return 0; }else { return 1; } } }); }
结果
1 16 43 32 3 18 45 22 42 31 2 17 44 21 4 19 15 56 53 60 33 64 23 46 30 41 58 63 54 61 20 5 57 14 55 52 59 34 47 24 40 29 38 35 62 51 6 9 13 36 27 50 11 8 25 48 28 39 12 37 26 49 10 7
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/121665.html
1.递归实现 ①不考虑相同数 /** * 二分查找,不考虑有相同数的情况(递归) * @param arr * @param left * @param right * @param findVal * @return */public stati...
学习资料 迪杰斯特拉计算的是单源最短路径,而弗洛伊德计算的是多源最短路径 代码 public class Main { //不能设置为Integer.MAX_VALUE,否则两...
阅读 1507·2023-04-26 01:55
阅读 840·2021-10-08 10:04
阅读 759·2021-09-30 09:47
阅读 3332·2021-09-24 09:47
阅读 1428·2019-08-30 15:54
阅读 537·2019-08-30 15:53
阅读 445·2019-08-30 15:52
阅读 892·2019-08-30 15:44