八數碼問題

2021-10-16 12:19:16 字數 1932 閱讀 5957

八數碼

題目描述

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