用最簡單的方法解決八數碼問題

2021-10-10 18:42:45 字數 2171 閱讀 4709

在九宮格裡放在1到8共8個數字還有乙個是空格,與空格相鄰的數字可以移動到空格的位置,問給定的狀態最少需要幾步能到達目標狀態

1.需要定義三個陣列

2.狀態轉移

每次只能像上下左右四個方向移動一格

轉移後狀態陣列與前乙個陣列只有兩個元素不同為方便程式處理給移動方向進行編碼定義兩個陣列:

dx=     

dy=

方向:上 下 左 右

狀態轉換時需要換算下標:先把一維陣列下標轉化為二維陣列下標,進行轉換以後再將二維下標轉換成一維陣列下標。

3.使用佇列進行廣度優先演算法

4.查重方法

用stl的集合

首先定義乙個儲存int型別的集合

將狀態陣列對映到整數

判斷該整數是否在集合裡面,如果不在,則插入此整數

5.使用棧來對最後得到的最小步驟經過的轉換狀態列印

首先檢索father 陣列,將得到值存入棧,當檢索到father[i]所存的值為1則停止檢索

進行出棧操作,列印下標是棧內元素的狀態陣列

#include

#include

#include

#include

using

namespace std;

typedef

int state[9]

;const

int maxstate =

4000000

;state state[maxstate]

, goal;

//定義狀態陣列,目標陣列

int dist[maxstate]

;//儲存到達此次狀態需要步驟次數

int father[maxstate]

;//儲存前繼狀態的下標

int dx[4]

=;int dy[4]

=;set<

int> vis;

//查重集合

stack <

int> father_sub;

//儲存前繼狀態的下標

intseek_state()

}int x = z /3;

int y = z %3;

int temp_z;

for(

int i =

0; i <

4; i++)if

(vis.

count

(v)==0)

rear++;}

}}front++;}

return-1

;}intmain()

cout <<

"請輸入初始狀態:"

;for

(int i =

0; i <

9; i++

)cout <<

"請輸入目標狀態:"

;for

(int i =

0; i <

9; i++

)int v =0;

for(

int j =

0; j <

9; j++

) vis.

insert

(v);

//將初始狀態存入查重集合

int min_count =

seek_state()

;//執行搜尋演算法

八數碼問題簡單解決辦法

八數碼問題是乙個經典的bfs問題,把棋局看成乙個狀態圖,共有9!種狀態。從初始棋局開始,每次轉移到下個狀態,直到目標棋局為止。仔細分析可知,八數碼的關鍵是判重,如果不去除重複狀態,程式會產生很多無效狀態,從而複雜度大大增加 bfs cantor 0表示空格所在位置 初始棋局 1 2 3 0 8 4 ...

C STL解決八數碼問題

先放原始碼 大部分借鑑了書本的 隨後對部分 進行解釋 include include include define len 362880 using namespace std 八數碼問題 struct node int dir 4 2 int vis len long int factory in...

簡單的八數碼問題(BFS)

時間限制 1 sec 記憶體限制 256 mb 提交 9 解決 7 提交 狀態 討論版 在3 3的棋盤上,擺有八個棋子,每個棋子上標有1至8的某一數字。棋盤中留有乙個空格,空格用0來表示。空格周圍的棋子可以移到空格中。要求解的問題是 給出一種初始布局 初始狀態 和目標布局 為了使題目簡單,設目標狀態...