時間限制: 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...