複習 BFS 八數碼20 8 24

2021-10-23 18:38:24 字數 1605 閱讀 1866

在乙個3×3的網格中,1~8這8個數字和乙個「x」恰好不重不漏地分布在這3×3的網格中。

例如:1 2 3

x 4 6

7 5 8

在遊戲過程中,可以把「x」與其上、下、左、右四個方向之一的數字交換(如果存在)。

我們的目的是通過交換,使得網格變為如下排列(稱為正確排列):

1 2 3

4 5 6

7 8 x

例如,示例中圖形就可以通過讓「x」先後與右、下、右三個方向的數字交換成功得到正確排列。

交換過程如下:

1 2 3 1 2 3 1 2 3 1 2 3

x 4 6 4 x 6 4 5 6 4 5 6

7 5 8 7 5 8 7 x 8 7 8 x

現在,給你乙個初始網格,請你求出得到正確排列至少需要進行多少次交換。

輸入格式

輸入佔一行,將3×3的初始網格描繪出來。

例如,如果初始網格如下所示:

1 2 3

x 4 6

7 5 8

則輸入為:1 2 3 x 4 6 7 5 8

輸出格式

輸出佔一行,包含乙個整數,表示最少交換次數。

如果不存在解決方案,則輸出」-1」。

輸入樣例:

2 3 4 1 5 x 7 6 8

輸出樣例

19

將每乙個狀態用一串字元來表示,進行bfs(將開始的狀態看為起點,將最後的狀態看做終點)。

1、如何表示狀態?如何把每個狀態存到 佇列 裡面?

2、如何表示距離(步數)?

3、如何判斷當前狀態的下乙個狀態有哪些?

難點:狀態轉移

1、一種比較簡單的方式是用字串來表示狀態。

3、 1、先恢復成乙個3x3的狀態。

2、移動。

3、恢復。

#include

using

namespace std;

intbfs

(string start)

, dy[4]

=;//深搜開始

while

(q.size()

)swap

(t[k]

, t[a *

3+ b]);

//別忘了返回狀態}}

}return-1

;//沒找到終點

}int

main()

//輸入字串

cout <<

bfs(start)

<< endl;

//bfs求距離

return0;

}補充:unordered_map::count

可以直接找到關聯容器裡裡面 是否有某個叫做某string形式的字串,有會返回1,沒會返回0.

// unordered_map::count

#include

#include

#include

int main (),

,};for

(auto

& x:

)return0;

}

八數碼 bfs,雜湊

很經典的搜尋,bfs部分沒什麼好講的,不是很難,值得注意的是如何判定走的路徑是否重複,本題採用的是雜湊來判重 include include includetypedef int state 9 const int maxn 1000003 int head maxn next maxn head陣...

八數碼題解(bfs

八數碼分析 本題是求最少交換次數,故先想到bfs,而本題的難點在於狀態和步數的儲存。以及狀態的轉移。如何記錄下x和乙個數交換後的狀態?如何記錄步數?主要思想 乙個巧妙的思想可以解決此類問題,狀態可以用string型別來記錄,求在3 3矩陣中的橫縱座標無非就是將其在string型別中的位序 假設為k ...

雙向BFS 八數碼問題

問題描述 在3 3的棋盤上,擺有八個棋子,每個棋子上標有1至8的某一數字。棋盤中留有乙個空格,空格用0來表示。空格周圍的棋子可以移到空格中。要求解的問題是 給出一種初始布局 初始狀態 和目標布局 目標狀態 找到一種最少步驟的移動方法,實現從初始布局到目標布局的轉變。例如 2 8 3 1 6 4 7 ...