在乙個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 ...