P1379 八數碼難題

2022-04-29 22:03:11 字數 1296 閱讀 3581

雙向bfs

右手進入傳送門

有乙個3*3的棋盤,其中有8個編號為1~8的棋子和乙個空格,空格四周的棋子可以向空格移動,

給出棋盤的初始狀態,問至少移動多少部可以達成目標狀態。

注意:棋盤的狀態用乙個九位數表示。

顯然是一道搜尋題,而且狀態比較好表示(乙個九位數),搜尋的量也不大,所以可以用bfs。

(這種移動棋子的題可以理解為空格向四周移動)

然後便可以單向bfs,用map判重即可,然後就莫名其妙的 ac,但還是不夠優

(ac了還不夠優,你還是人嗎)

雙向bfs

初步介紹

先簡單介紹一下,如果單純的單向bfs,搜尋的深度可能很大,要很多層才能搜到答案。

而雙向bfs可以剪掉很多不必要的枝達到優化,但是雙向bfs是只有確定目標狀態的情況下才可以用的,例如本題。

其實和單向的差不多,不過有一些地方要注意:

開乙個mapflag記錄每個點是從**來的。

開乙個mapans表示從自己的祖先開始用了多少步到這裡。

搜尋時會遇到三種情況:例如從i點遍歷到了j點:

初始化:ans起點和終點都為1,flag不同就行。其他點flag賦值-1(個人習慣)

然後就快樂ac

#include#include#include#include#include#includeusing namespace std;

int a,b=123804765,p[5][5],fx,fy;

int dx[5]=;

int dy[5]=;

queueq;

mapflag;

mapans;

void to_juzhen(int now) }}

return;

}int to_shulie()

}return x;

}void bfs()

if(flag[now]+flag[cur]==3)

flag[now]=flag[cur];

ans[now]=ans[cur]+1;

q.push(now);

swap(p[fx][fy],p[gx][gy]);}}

return;

}int main()

bfs();

return 0;

}

雙向bfs的使用

P1379 八數碼難題

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

P1379 八數碼難題

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

P1379 八數碼難題

當前的棋盤,空格的位置和走過的步數。棋盤可以用全域性變數來存。每次往上下左右四個方向搜即可。1.上下界剪枝 上界 不好求 下界 最好的情況就是 當前情況有多少個位子與目標狀態不同,即 sum sum g i j des i j 雖然下界對剪枝沒什麼用 2.搜尋順序優化 由於乙個地方可以重複走所以順序...