1944 年,特種兵麥克接到國防部的命令,要求立即趕赴太平洋上的乙個孤島,營救被敵軍俘虜的大兵瑞恩。
瑞恩被關押在乙個迷宮裡,迷宮地形複雜,但幸好麥克得到了迷宮的地形圖。
迷宮的外形是乙個長方形,其南北方向被劃分為 n 行,東西方向被劃分為 m 列, 於是整個迷宮被劃分為 n×m 個單元。
每乙個單元的位置可用乙個有序數對 (單元的行號, 單元的列號) 來表示。
南北或東西方向相鄰的 2 個單元之間可能互通,也可能有一扇鎖著的門,或者是一堵不可逾越的牆。
注意: 門可以從兩個方向穿過,即可以看成一條無向邊。
迷宮中有一些單元存放著鑰匙,同乙個單元可能存放 多把鑰匙,並且所有的門被分成 p 類,開啟同一類的門的鑰匙相同,不同類門的鑰匙不同。
大兵瑞恩被關押在迷宮的東南角,即 (n,m) 單元裡,並已經昏迷。
迷宮只有乙個入口,在西北角。
也就是說,麥克可以直接進入 (1,1) 單元。
另外,麥克從乙個單元移動到另乙個相鄰單元的時間為 1,拿取所在單元的鑰匙的時間以及用鑰匙開門的時間可忽略不計。
試設計乙個演算法,幫助麥克以最快的方式到達瑞恩所在單元,營救大兵瑞恩。
輸入格式
第一行有三個整數,分別表示 n,m,p 的值。
第二行是乙個整數 k,表示迷宮中門和牆的總數。
接下來 k 行,每行包含五個整數,\(x_,y_,x_,y_,g_i\):當 gi≥1 時,表示 \((x_,y_)\) 單元與 \((x2,y)\) 單元之間有一扇第 \(g_i\) 類的門,當 gi=0 時,表示 \((x_,y_)\) 單元與 \((x2,y)\) 單元之間有一面不可逾越的牆。
接下來一行,包含乙個整數 s,表示迷宮中存放的鑰匙的總數。
接下來 s 行,每行包含三個整數 \(x_,y_,q_i\),表示 \((x_,y_)\) 單元裡存在乙個能開啟第 \(q_i\) 類門的鑰匙。
輸出格式
輸出麥克營救到大兵瑞恩的最短時間。
如果問題無解,則輸出 -1。
資料範圍
\(|x_−x_|+|y_−y_|=1,\)
\(0≤g_i≤p,\)
\(1≤q_i≤p,\)
\(1≤n,m,p≤10,\)
\(1≤k≤150\)
輸入樣例:
4 4 9
91 2 1 3 2
1 2 2 2 0
2 1 2 2 0
2 1 3 1 0
2 3 3 3 0
2 4 3 4 1
3 2 3 3 0
3 3 4 3 0
4 3 4 4 0
22 1 2
4 2 1
輸出樣例:
14
樣例解釋:
迷宮如下所示:
拆點狀壓dp和bfs。n,m,s都很小。預處理每個格仔上有的鑰匙種類,以及方格之間的門和牆。然後從(0,0)開始跑bfs,把每個點拆成走到當前點有鑰匙s(二進位制),f[x][y][s]表示在(x,y)點有鑰匙s的走最少步數的狀態,對於每個點去更新它可以到達的點和具有鑰匙的狀態的最短距離。
#includeusing namespace std;
const int n=10,inf=0x3f3f3f3f;
int n,m,p;
int id(int x,int y)
int g[n*n][n*n]; //-1不通過 0通過 1~有門
int gg[n][n]; //0沒鑰匙
struct ac;
int y=;
int bfs());
while(!q.empty())
else
int ans=bfs();
if(ans==inf) cout<
else cout<
return 0;
}
拯救大兵瑞恩
題目描述 特種兵麥克接到命令要求營救被 敵軍俘虜的大兵瑞恩。瑞恩被關押在乙個迷宮裡,迷宮地形複雜,但幸好麥克得到了迷宮的 地形圖。迷宮的外形是乙個長方形,其南北方向被劃分為n行,東西方向被劃分為m列,於是整個迷宮被劃分為n m個單元。每乙個單元的位置可用乙個有序數對 單元的行號,單元的列號 來表示。...
AcWing1131 拯救大兵瑞恩(最短路)
這題主要問題是有些地方有鑰匙,這種型別我們之前在bfs種做到過,就是用狀壓dp多列舉一維鑰匙就行了,因為鑰匙不需要時間,所以每次走到取完鑰匙肯定是最優的 本題是二維的,不過轉成一維更方便。我們的dis陣列原先記錄的是點,現在記錄的是點和狀態。建圖是,先建門,將門與牆都插入乙個set便於查詢 建完這兩...
尺有所短,寸有所長 邁瑞 凱恩帝
今天去面邁瑞,等待期間,幾同學在狂貶低邁瑞和凱恩帝的技術含量,還有專利等問題。其實,邁瑞和凱恩帝做的事情在國外看來確實沒太多技術含量,現在還做不了高階產品。但是,至少他們一直在努力,而且,在一窮二白的基礎上取得了初步的成果。比起絕大多數中國企業,他們是值得驕傲的。更不用說比起某些 想想晚清和 時期的...