雙向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.搜尋順序優化 由於乙個地方可以重複走所以順序...