HDU 1254 推箱子 C 優先佇列 bfs

2021-08-14 05:26:14 字數 2193 閱讀 7842

推箱子是乙個很經典的遊戲.今天我們來玩乙個簡單版本.在乙個m*n的房間裡有乙個箱子和乙個搬運工,搬運工的工作就是把箱子推到指定的位置,注意,搬運工只能推箱子而不能拉箱子,因此如果箱子被推到乙個角上(如圖2)那麼箱子就不能再被移動了,如果箱子被推到一面牆上,那麼箱子只能沿著牆移動.

現在給定房間的結構,箱子的位置,搬運工的位置和箱子要被推去的位置,請你計算出搬運工至少要推動箱子多少格.

輸入格式

輸入資料的第一行是乙個整數t(1<=t<=20),代表測試資料的數量.

然後是t組測試資料,每組測試資料的第一行是兩個正整數m,n(2<=m,n<=7),代表房間的大小.

然後是乙個m行n列的矩陣,代表房間的布局,其中0代表空的地板,1代表牆,2代表箱子的起始位置,3代表箱子要被推去的位置,4代表搬運工的起始位置.

輸出格式

對於每組測試資料,輸出搬運工最少需要推動箱子多少格才能幫箱子推到指定位置,如果不能推到指定位置則輸出-1.

樣例輸入

1 5 5

0 3 0 0 0

1 0 1 4 0

0 0 1 0 0

1 0 2 0 0

0 0 0 0 0

樣例輸出

4求最短時間一般用的是bfs。但這道題用普通的bfs會wa,因為要求的最短路是推動箱子的最小步數,而普通的bfs是搬運工移動的最小次數,而移動的次數少不一定能代表推動箱子次數少,例如下面這組資料:

1 3 5

1 1 4 0 0

0 2 0 0 0

0 3 0 0 0

若用普通的bfs執行這組資料,得到的結果是5,而用優先佇列+bfs執行結果是3,因為此時推動箱子次數少,但搬運工走的步數要多(若想要只推動3次箱子則必須繞幾個彎才能達到終點)。故普通的bfs會wa。

雖然優先佇列可以用c++的stl模板庫里的priority_queue,如下:

priority_queuew; //這是元素大的排前面,若想要元素小的排前面則要用priority_queue,greater> w;
但是需要過載乙個<,並注意在前面加上friend,如下:

friend

inline

bool

operator

< (node a,node b)

每次bfs完都要把佇列裡剩下的元素全部彈出,如下:

while(!w.empty())   w.pop();
首先要用乙個陣列來記錄狀態。這裡由於人和箱子的位置都要記錄,所以應用乙個四維陣列來記錄(其實由於n和m不超過7,二維陣列,十位表示橫座標,個位表示縱座標也是可以的)。

當人碰到箱子的時候箱子就向同樣的方向移動一次。

其他和普通的bfs是一樣的,就不詳細說了。

搜完所有狀態後若仍無解則返回-1。

#include

#include

#include

using

namespace

std;

const

int size=13;

const

int dx = ;

const

int dy = ;

intmap[size][size];

bool memory[size][size][size][size]; //判重陣列

int m,n,x1,y1,x2,y2,x3,y3;

struct node

};priority_queuew;

void push_queue(int x,int y,int bx,int by,int time)

int read()

while(ch>='0' && ch<='9')

return x*f;

}void init() }}

while(!w.empty()) w.pop(); //將佇列裡剩下的元素彈出佇列

push_queue(x1,y1,x3,y3,0);

}inline

bool judge(int x,int y)

int bfs() else }}

}return -1;

}int main()

return

0;}

hdu 1254 推箱子遊戲

這個題目我就不說,鏈結在這裡 主要我想說的是,一開始是我用2個三圍陣列來分別標記人和箱子走過的四個方向,但不知怎麼回事行不通。於是就用乙個四維陣列來標記狀態,嘻嘻,過了。好吧,還是直接上 了。1 include2 include3 include4 5using namespace std 6int...

HDU 1254 推箱子(搜尋)

by cxlove 以前就做過的一題,重溫一下 推箱子遊戲,首先廣搜箱子的路徑,每一次移動都要判斷人是否能到達指定位置 bfs,dfs都行 我採用兩次bfs解決問題 在箱子的移動中,判重的時候需要乙個三維陣列,箱子從不同方向過來,人的位置是不一樣的,也就意味著狀態不一樣 id cxlove incl...

hdu 1254 推箱子遊戲

這個題目我就不說,鏈結在這裡 主要我想說的是,一開始是我用2個三圍陣列來分別標記人和箱子走過的四個方向,但不知怎麼回事行不通。於是就用乙個四維陣列來標記狀態,嘻嘻,過了。好吧,還是直接上 了。1 include2 include3 include4 5using namespace std 6int...