15騎士周遊問題(馬踏棋盤問題)

2021-07-26 21:46:21 字數 1571 閱讀 7422

輸出5*5棋盤的騎士周遊的方法數:

#include

#include

#define x 5

#define y 5

int chess[x][y]=};//二維陣列的初始化,兩個大括號

int count=0;

void print()

printf("\n");//這裡的\n放置也非常巧妙,一行之後換行

}printf("\n");//一趟走完也換一次行,親測這個沒必要換行,因為visit中已經有換行;用了也沒事,就多乙個換行而已

}void visit(int x,int y,int tag)

/*1、乙隻在中間的馬,假如四周都可以走,那麼他有八種走法;每個象限各兩種;

2、用回溯法,每次遞迴哪個位置是隨機的,取決於你安排的if的位置前後

3、有乙個遞迴變數tag每次遞增1,是用來判斷當tag等於棋盤大小時,則算一次走完全盤

4、這裡有個count全域性變數也非常重要,是用來記錄總共有多少個走法;

仔細體會體會count和tag的不同之處,都是遞迴加1,但是做法和作用不太一樣

5、還有這裡的x,y也是屬於全域性變數,要注意理解

6、橫縱座標的問題,這裡的陣列象限判斷出錯了,i正負,表示上下移動,即行方向移動,不要和數學中的混淆;

j正負,表示左右移動,即列方向移動,

*///第一象限右一進二 第一象限進一右二

if(i+1

21][j+2]==0)

//第一象限右二進一 第一象限進二右一

if(i+2

12][j+1]==0)

//第二象限左一進二 第四象限退一右二

if(i-1>=0&&j+2

1][j+2]==0)

//第二象限左二進一 第四象限退二右一

if(i-2>=0&&j+1

2][j+1]==0)

//第三象限左一退二 第三象限退一左二

if(i-1>=0&&j-2>=0&&chess[i-1][j-2]==0)

//第三象限左二退一 第三象限退二左一

if(i-2>=0&&j-1>=0&&chess[i-2][j-1]==0)

//第四象限右一退二 第二象限進一左二

if(i+1

2>=0&&chess[i+1][j-2]==0)

//第四象限右二退一 第二象限進二左一

if(i+2

1>=0&&chess[i+2][j-1]==0)

/*這一步重置標記位置為0,也是相當重要,作用是讓給下一種走法;

這個chess放在這裡很巧妙,可能有點難理解:chess是放在所有八個遞迴函式的最後,也就是說,第一次

執行這個chess是第乙個tag=x*y,比如5*5就是25;然後從25開始,依次回退,

這裡還有乙個難點,就是這裡是回溯法,所以更準確的說不是,從25開始依次回退到1;而是從25回退,讓後再檢測其他相鄰結點;

有點像深度優先查詢;

*/chess[i][j]=0;

}int main()

資料結構與演算法10 馬踏棋盤問題(騎士周遊問題)

問題描述 在乙個西洋棋的棋盤上,乙個馬按照它的規則如何才能從乙個點出發遍歷每乙個位置,且每個點只訪問一次。問題分析 這是乙個深搜的問題,沿著一條路前進直到遍歷全部的點,那就完成了整個的過程。如果不行,就回退一步,換個方向繼續前進。這可以用遞迴很方便地實現。注意到馬在某個位置最多有8個方向可以走,因此...

馬踏棋盤問題(dfs求解)

問題描述 8 8的棋盤,剛開始讓馬在棋盤的任意乙個位置上,讓馬踏日,有八個方向 判斷沒踏過並且可踏,就踏,直到踏完所有的格仔 cnt 64 呼叫printchess函式。在外層另外加上兩層,確保 8 8 方格中的每乙個格仔都有8中不同的選擇 重點 為了確保每個格仔能走日字,而且選擇的可能性等同,初始...

騎士遊歷問題(馬踏棋盤)解析(c )

解題思路 這是一道經典的遍歷問題 dfs 由於題目要求遍歷全部,那麼肯定要做標記,因此立馬想到dfs深度優先演算法。具體思路如下 了解西洋棋以及西洋棋騎士的走法 西洋棋和中國象棋,大同小異,畢竟中國象棋是老祖先。西洋棋棋子放在格仔中,中國象棋放在點上,且西洋棋有64個格仔。西洋棋的騎士和中國象棋的馬...