馬踏棋盤之遞迴實現
問題描述:
所謂“馬踏棋盤”問題,就是指在中國象棋的棋盤上,用馬的走法走遍整個棋盤,在8*8的方格中,每個格都要遍歷,且只能遍歷一次。
我們把棋盤抽象成一個二維資料,輸入起始位置的座標(x,y),根據馬的“日”字走法,將馬走的步數寫入二維陣列,然後輸出。下面是一種走法:
解決方法:
我們從圖中可以看到,一個位置的馬可以有八個不同方向的下一步。如何表示下一步呢?
設當前馬的座標為(x,y),則下一步為(x-2,y+1)、(x-1,y+2)、(x+1,y+2)、(x+2,y+1)、(x+2,y-1)、(x+1,y-2)、(x-1,y-2)、(x-2,y-1)八個方向。
我們設兩個全域性陣列fx[8]={1,2,2,1,-1,-2,-2,-1},fy[8]={2,1,-1,-2,-2,-1,1,2},則上面的八個方向的點可以表示為:(x+fx[i],y+fy[i]),i為0~7。
我們先設一個陣列a[8][8]來存放馬的遍歷路徑。
首先輸入一個起始座標,然後從起始點開始進行深度優先搜尋。從第1步找第2步的座標,然後從第2步找第3步,再從第3步找第4步……。直到找到第64步也就完成任務了。
當然,每一個馬都有八個下一步的選擇,我們在滿足要求的點中任意找一個進行遍歷,當八個點都不滿足要求時,就回溯的上一步,找其他點進行遍歷。
下一步需要滿足的條件:點(x,y)要在棋盤上,即0<x,y<8,同時a[x][y]要未遍歷過。
下面是我的全部程式碼,僅供參考:
#include<stdio.h>
int fx[8]={1,2,2,1,-1,-2,-2,-1},fy[8]={2,1,-1,-2,-2,-1,1,2},a[8][8];
//Output()函式進行輸出遍歷結果
void Output()
{
int i,j;
for(i = 0;i < 8;i++,printf("\n"))
for(j = 0;j < 8;j++)
printf("%3d",a[i][j]);
}
/*Check()函式檢查xx、yy代表的點是否滿足條件,滿足則返回1.
*條件:在8*8的棋盤邊界內,且該點未遍歷。
*/
int check(int xx,int yy)
{
if(xx >= 0 && xx < 8 && yy >= 0 && yy < 8 && a[xx][yy] == 0)
return 1;
return 0;
}
/*x、y表示起點的橫座標和縱座標,dep為遞迴的深度,代表當前馬是第幾個馬。
*Find()函式搜尋起點的下一個結點,然後以下一個結點為起點,進行遞迴搜尋。
*當深度達到64時表示遍歷完成,進行輸出。
*/
int Find(int x,int y,int dep)
{
int i,xx,yy;
for(i = 0;i < 8;i++)
{
xx = x + fx[i];
yy = y + fy[i];
if(check(xx,yy) == 1) //檢查點a[xx][yy]是否滿足條件
{
a[xx][yy] = dep;
if(dep == 64)
{
Output();
return 1;
}
if(Find(xx,yy,dep+1) == 1) //如果返回的是1,表示遍歷完成。
return 1;
else //如果返回的不是1,表示遍歷未完成,繼續搜尋。
a[xx][yy] = 0;
}
}
return 0;
}
void main()
{
/*x和y代表馬的座標。dep為遞迴的深度,代表當前馬是第幾個馬*/
int i,j,x,y;
int dep = 1;
/*陣列a[8][8]代表棋盤,遍歷之前先初始化*/
for(i = 0;i < 8;i++)
for(j = 0;j < 8;j++)
a[i][j] = 0;
printf("請輸入x,y:\n");
scanf("%d,%d",&x,&y);
a[x-1][y-1] = 1;
if(Find(x-1,y-1,2) == 1) //尋找路徑,找到了則返回1,否則返回0。
printf("Success!\n");
else
printf("Failed!\n");
}
以上思路相對比較簡單,有點類似迷宮問題,只需進行深度優先搜尋和回溯就能解決。但是執行的效率很低,而且還只輸出了一條路徑。如果需要輸出幾千或者幾萬條路徑的話,必須進行優化才行。
轉載請註明出處,謝謝!(原文連結:http://blog.csdn.net/bone_ace/article/details/39452179)
相關文章
- 馬踏棋盤(棧實現)
- 馬踏棋盤之貪心演算法優化演算法優化
- 馬踏棋盤演算法(騎士周遊問題)----遞迴與貪心優化演算法演算法遞迴優化
- lambda實現遞迴遞迴
- 棧實現遞迴遞迴
- 遞迴實現原則遞迴
- strcmp的遞迴實現遞迴
- 兩種遞迴方式實現迴文字遞迴
- 資料結構:稀疏棋盤的實現資料結構
- 全排列的實現之遞迴版與迭代版遞迴
- 16×16大小棋盤的五子棋小程式 Java實現Java
- 殘缺棋盤 android實現顏色填充Android
- 圖的遍歷演算法-馬遍歷棋盤演算法
- python-動態規劃的遞迴、非遞迴實現Python動態規劃遞迴
- 遞迴和非遞迴分別實現求n的階乘遞迴
- 斐波那契數列的遞迴和非遞迴實現遞迴
- oracle中的遞迴sql查詢 connect by prior實現遞迴Oracle遞迴SQL
- 原:八皇后問題的遞迴和非遞迴Java實現遞迴Java
- 尾遞迴實現深複製遞迴
- 用 Promise + 遞迴實現灌酒動畫Promise遞迴動畫
- C#實現FFT(遞迴法)C#FFT遞迴
- 遞迴實現指數型列舉遞迴
- 如何遞迴實現陣列求和遞迴陣列
- 遞迴實現漢諾塔問題遞迴
- c#遞迴實現 階乘C#遞迴
- 迴圈_推導式_繪製棋盤_函式函式
- 棋盤完美覆蓋數(小規模原理實現)
- 全域性元件實現遞迴樹,避免迴圈引用元件遞迴
- 歸併排序的非遞迴實現排序遞迴
- Mysql 實現樹狀遞迴查詢MySql遞迴
- 【演算法】遞迴實現全排列演算法遞迴
- Java實現多級選單(遞迴)Java遞迴
- 函式之遞迴函式遞迴
- 課時22:函式:遞迴是神馬函式遞迴
- 遍歷二叉樹的遞迴與非遞迴程式碼實現二叉樹遞迴
- 二分法的簡單實現——-遞迴和非遞迴遞迴
- Android遍歷所有控制元件的遞迴和非遞迴實現Android控制元件遞迴
- 【演算法拾遺】二分查詢遞迴非遞迴實現演算法遞迴