機械人搬重物 BFS

2022-02-13 08:21:12 字數 3507 閱讀 4261

時間限制: 1 sec  記憶體限制: 256 mb

機械人移動學會(rmi)現在正嘗試用機械人搬運物品。機械人的形狀是乙個直徑 1.6 公尺的球。在試驗階段,機械人被用於在乙個儲藏室中搬運貨物。儲藏室是乙個 n×m 的網格,有些格仔為不可移動的障礙。機械人的中心總是在格點上,當然,機械人必須在最短的時間內把物品搬運到指定的地方。機械人接受的指令有:向前移動 1 步(creep);向前移動 2 步(walk);向前移動 3 步(run);向左轉(left);向右轉(right)。每個指令所需要的時間為 1 秒。請你計算一下機械人完成任務所需的最少時間。

第一行為兩個正整數 n,m (n,m ≤ 50),下面 n 行是儲藏室的構造,0 表示無障礙,1 表示有障礙,數字之間用乙個空格隔開。接著一行有 4 個整數和 1 個大寫字母,分別為起始點和目標點左上角網格的行與列,起始時的面對方向(東 e,南 s,西 w,北 n),數與數,數與字母之間均用乙個空格隔開。終點的面向方向是任意的。

乙個整數,表示機械人完成任務所需的最少時間。如果無法到達,輸出 −1。

輸入 9 10

0 0 0 0 0 0 1 0 0 0

0 0 0 0 0 0 0 0 1 0

0 0 0 1 0 0 0 0 0 0

0 0 1 0 0 0 0 0 0 0

0 0 0 0 0 0 1 0 0 0

0 0 0 0 0 1 0 0 0 0

0 0 0 1 1 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0

1 0 0 0 0 0 0 0 1 0

7 2 2 7 s

輸出 12

題意:在n*m的網格中,乙個佔據四個格仔的物體要從起點走到終點,中途不能碰到障礙物,支援前進1,2,3步或者左右轉向,耗時都為一秒,求最短耗時。

先貼**(我知道你們是來看這個的)

自認為碼風很乾淨的**:

1 #include2 #include3 #include4

using

namespace

std;

5struct nodenow;

6int n,m,sx,sy,ex,ey,ans,state,g[55][55],mark[55][55][5];7

//sx,sy起點座標(start) ,ex,ey終點座標(end) 8//

state標記最開始方向,g儲存地圖,mark標記9//

mark的三個下標分別確定行,列,方向

10int d[4]=,d2[3]=;

11//

d用於轉換方向,d2用於移動

12char

ch;13 queueq;

14bool check(int x,int

y)15

22void bfs(int x,int y,int

state)

23);

29while(!q.empty())

3053

if(k<=j) continue;//

如果中途退出過表示不能移動

54 }//

以下**複製略作修改即可

55else

if(tz==-2)//

西 56

62if(k<=j) continue;63

}64else

if(tz==1)//

南 65

71if(k<=j) continue;72

}73else

if(tz==-1)//

北 74

80if(k<=j) continue;81

}82if(mark[tx][ty][tz+2]>ts)

83);

85 mark[tx][ty][tz+2]=ts;86}

87}88}

89}90return;91

}92intmain()

93//

東西南北四個方向

105bfs(sx,sy,state);

106int a=min(mark[ex][ey][0],mark[ex][ey][1

]);107

int b=min(mark[ex][ey][3],mark[ex][ey][4

]);108 ans=min(a,b);//

尋找在終點時的最小步數

109if(ans!=0x7fffffff) printf("

%d\n

",ans);

110else printf("

-1\n

");//

若沒有被更新過代表無解

111return0;

112 }

分塊解析:

bfs基本思路:把所有可行的、未標記過的點依次入隊(當然了首先入隊的是起點),依次取出後按所有可能性拓展,若沒有可以再拓展的點代表搜尋完畢。

注意點1:乙個機械人佔據四個格仔,所以**中都使用左上角的座標來儲存。

注意點2:題目中描述的允許操作是

①向前移動 1 步(creep

②向前移動 2 步(walk

③向前移動 3 步(run

向左轉(left

向右轉(right

在這裡,允許的操作是左右旋轉,所以我們需要巨集觀的東南西北來判斷機械人的旋轉方向。

不妨使用2,-2,1,-1分別代表東、西、南、北,只要依次讓機械人嘗試這些方向,如果當前嘗試的方向與原來的朝向的和為0,代表向後轉;同樣的如果相同即沒有旋轉,其他情況都為向左或右旋轉。

旋轉了就必須移動(這不是廢話嘛......不然你轉他幹什麼),所以可以將旋轉與移動合併為一次操作計時。

注意在mark陣列記錄的時候要記錄2個資料:座標以及朝向。只有在同一地點、同一種朝向的情況下,如果當前方案比之前mark標記的最優方案更優才能更新。

注意點3:判斷目前搜尋到的點是否可行,**如下

bool check(int x,int

y)

要注意乙個點!機械人不管是爬還是走還是跑,過去的途中也不可以碰到障礙物!

例如樣例中的這個圖,機械人(左上角)從網格第四行第一列直接向北跑三格到第一行第一列,若只判斷左上角的目標地點是否可行的話,是可以移動的,但實際上這條路線是不被允許的,因為移動過程中會被障礙物擋住(畢竟機械人不是飛過去的),我就是因為這個wa了三次qaq。所以我的做法是移動過程中碰到的的點依次判斷是否可行。具體實現過程見**第45行至81行。

機械人搬重物

時間限制 1 sec 記憶體限制 128 mb 提交 28 解決 13 提交 狀態 討論版 機械人移動學會 rmi 現在正嘗試用機械人搬運物品。機械人的形狀是乙個直徑1.6公尺的球。在試驗階段,機械人被用於在乙個儲藏室中搬運貨物。儲藏室是乙個n m的網格,有些格仔為不可移動的障礙。機械人的中心總是在...

CSU 1975 機械人搬重物(BFS)

time limit 1 sec memory limit 128 mb submitted 64 solved 10 機械人移動學會 rmi 現在正嘗試用機械人搬運物品。機械人的形狀是乙個直徑1.6公尺的球。在試驗階段,機械人被用於在乙個儲藏室中搬運貨物。儲藏室是乙個n m的網格,有些格仔為不可移...

P1126 機械人搬重物 複雜bfs

p1126 機械人搬重物 傳送門 說實話這道題蠻複雜度,需要注意的東西比較多.如對於乙個座標,可能有四個方向的情況,所以vis陣列用三維來表示.機械人的旋轉和方向是用num 4來表示的,num為0代表向南,為1代表向東,為2代表向北,為3代表向西,那麼只要我根據前乙個狀態的方向num,調整num 1...