八數碼
題目描述
在乙個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
把「x」與上下左右方向數字交換的行動記錄為「u」、「d」、「l」、「r」。
現在,給你乙個初始網格,請你通過最少的移動次數,得到正確排列。
輸入格式
輸入佔一行,將3×3的初始網格描繪出來。
例如,如果初始網格如下所示:
1 2 3
x 4 6
7 5 8
則輸入為:1 2 3 x 4 6 7 5 8
輸出格式
輸出佔一行,包含乙個字串,表示得到正確排列的完整行動記錄。如果答案不唯一,輸出任意一種合法方案即可。
如果不存在解決方案,則輸出」unsolvable」。
輸入樣例:
2 3 4 1 5 x 7 6 8
輸出樣例
ullddrurdllurdruldr
分析:
這道題可以用bfs來做,或a
∗a^*
a∗演算法,a
∗a^*
a∗演算法以後補上,這裡講解bfs做法,bfs做法比較簡單理解,利用uno
rder
ed_m
ap
unordered\_map
unorde
red_
map來儲存已經訪問過的路徑和當前長度,順便儲存一下最短距離即可。
編譯環境:c++11,這裡,可以將devc++設定支援c++11
**如下
#include
#include
#include
#include
#include
#include
using
namespace std;
int dx[4]
=;int dy[4]
=;char op=
"dulr"
;//方向
struct node
;int
find
(string s)
void
bfs(string st)
int k=
find
(f.s)
;int kx=k/
3,ky=k%3;
for(
int i=
0;i<
4;i++
) f.t=t;
//改變回原狀態
swap
(f.s[k]
,f.s[nx*
3+ny]);
}}} cout<<
"unsolvable"
intmain()
bfs(st)
;return0;
}
八數碼問題還有乙個比較有意思的地方,就是初始狀體和最終狀態(這裡"12345678x"),的逆序對數量的奇偶性相同,這樣我們可以提前判斷出是否可解。 八數碼問題
八數碼問題 一.八數碼問題 八數碼問題也稱為九宮問題。在3 3的棋盤,擺有八個棋子,每個棋子上標有1至8的某一數字,不同棋子上標的數字不相同。棋盤上還有乙個空格,與空格相鄰的棋子可以移到空格中。要求解決的問題是 給出乙個初始狀態和乙個目標狀態,找出一種從初始轉變成目標狀態的移動棋子步數最少的移動步驟...
八數碼問題
2 6 4 1 3 7 0 5 8 8 1 5 7 3 6 4 0 2 樣例輸出 還有就是重判的問題,如何重判呢?第一種方法 把排列變成整數,然後只開乙個一維陣列,也就是說設計一套排列的編碼和解碼函式,把0 8的全排列和0 362879的整數意義一一對應起來。時間效率高,但編碼解碼法適用範圍並不大,...
八數碼問題
八數碼問題 題意 編號為1 8的8個正方形滑塊被擺成3行3列 有乙個格仔留空 如下圖所示 每次可以把與空格相鄰的滑塊 有公共邊才算相鄰 移到空格中,而他原來的位置 就成為了新的空格。如果無法到達目標局面,則輸出 1。2 6 4 13 75 8 移到後 8 1 5 73 642 樣例輸入 2 6 4 ...