1. 程式人生 > 其它 >【回溯】原生的馬踏棋盤——賊強

【回溯】原生的馬踏棋盤——賊強

技術標籤:五大常用演算法dfs演算法

問題描述

在N*N棋盤上,任意一個位置放置一個棋子馬,要能選擇一套合適的移動路線,按象棋中“馬走日”的移動規則不重複地遍歷棋盤上每一個位置點。

輸入

第一行,一個正整數n。
第二行包含兩個整數,表示原點在棋盤中的位置

輸出

輸出遍歷棋盤的路徑或者“沒有找到全遍歷路徑


解法:回溯搜路徑

思路

(1)從源點開始,向各個方向試探
(2)如果當前跳法符合條件,就繼續以當前位置為源點,向各個方向試探
(3)如果當前位置已經被佔了,就回退到上一個位置,向其他方向跳
(4)棋盤已滿時,遍歷輸出,結束程式

程式碼

import java.util.Scanner;
/** * 象棋中馬的軌跡 * * @author Administrator * */ public class Main { /** * 儲存棋盤 */ static int[][] arr; /** * 棋盤的寬度 */ static int n; /* 馬跳棋盤的8個方向 */ static int[][] dir = { { -1, -2 }, { -1, 2 }, { -2, 1 }, { -2, -1 }, { 1, 2 }, { 1, -2 }, { 2, -1 },
{ 2, 1 } }; public static void main(String[] args) { @SuppressWarnings("resource") Scanner scanner = new Scanner(System.in); n = scanner.nextInt(); arr = new int[n][n]; int startI = scanner.nextInt(); int startJ = scanner.nextInt(); // 馬開始跳的起點
arr[startI][startJ] = 1; findPath(startI, startJ, 2); System.out.println("沒有找到全遍歷路徑"); } /** * 在棋盤中尋找馬是否有可行路徑,有則打出一個 * * @param startI * @param startJ */ private static void findPath(int startI, int startJ, int num) { // 停止條件:已經遍歷整個棋盤 if (num == n * n + 1) { dispaly(arr); System.exit(0); } else { for (int k = 0; k < 8; k++) { int ii = startI + dir[k][0]; int jj = startJ + dir[k][1]; if(judge(ii, jj)){ // 走過這裡標記 arr[ii][jj] = num; findPath(ii, jj, num + 1); // 走過,但是路徑走不通,馬跳回來,取消這裡的標記 arr[ii][jj] = 0; } } } } private static boolean judge(int ii, int jj) { if(ii >= 0 && ii < n && jj >= 0 && jj < n){ if(arr[ii][jj] == 0){ return true; } } return false; } /** * 遍歷輸出 * @param arr */ private static void dispaly(int[][] arr) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { System.out.printf("%3d", arr[i][j]); } System.out.println(); } System.out.println(); } }

執行結果

大一期末實訓題目~真好玩兒