摘要:騎士周游問題又叫馬踏棋盤問題未優化前沒有策略定義棋盤的行數和列數定義棋盤上的某個點是否被訪問過記錄是否周游結束從第一行第一列開始走,第一次走算第一步,即展示下是棋盤,
騎士周游問題又叫馬踏棋盤問題
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
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/121665.html
摘要:應用分治法是一種很重要的算法。字面上的解釋是分而治之,就是把一個復雜的問題分成兩個或更多的相同或相似的子問題,再把子問題分成更小的子問題直到最后子問題可以簡單的直接求解,原問題的解即子問題的解的合并。 ...
摘要:問題勝利鄉有個村莊現在需要修路把個村莊連通各個村莊的距離用邊線表示權比如距離公里問如何修路保證各個村莊都能連通并且總的修建公路總里程最短代碼重點理解中的三層循環 問...
摘要:遞歸實現不考慮相同數二分查找,不考慮有相同數的情況遞歸找到了考慮有相同數二分查找考慮有相同元素的情況遞歸要查找的值 1.遞歸實現 ①不考慮相同數 /** * 二分查...
摘要:學習資料迪杰斯特拉計算的是單源最短路徑,而弗洛伊德計算的是多源最短路徑代碼不能設置為,否則兩個相加會溢出導致出現負權創建頂點和邊 學習資料 迪杰斯特拉計算的是單源最...
摘要:例題假設存在如下表的需要付費的廣播臺,以及廣播臺信號可以覆蓋的地區。 例題 假設存在如下表的需要付費的廣播臺,以及廣播臺信號可以覆蓋的地區。如何選擇最少的廣播臺,讓...
閱讀 1815·2023-04-26 01:55
閱讀 1078·2021-09-30 09:47
閱讀 1672·2019-08-30 15:54
閱讀 740·2019-08-30 15:53
閱讀 692·2019-08-30 15:52
閱讀 1133·2019-08-30 15:44
閱讀 2409·2019-08-30 14:06
閱讀 1057·2019-08-29 16:39