題目表述不難看出,本題是一道搜尋,而且本題需要記錄鑰匙的攜帶情況以判斷門是否可以通過的問題ignatius再次被魔王抓走了(搞不懂他咋這麼討魔王喜歡)……
這次魔王汲取了上次的教訓,把ignatius關在乙個n*m的地牢裡,並在地牢的某些地方安裝了帶鎖的門,鑰匙藏在地牢另外的某些地方。剛開始ignatius被關在(sx,sy)的位置,離開地牢的門在(ex,ey)的位置。ignatius每分鐘只能從乙個座標走到相鄰四個座標中的其中乙個。魔王每t分鐘回地牢視察一次,若發現ignatius不在原位置便把他拎回去。經過若干次的嘗試,ignatius已畫出整個地牢的地圖。現在請你幫他計算能否再次成功逃亡。只要在魔王下次視察之前走到出口就算離開地牢,如果魔王回來的時候剛好走到出口或還未到出口都算逃亡失敗。
輸入每組測試資料的第一行有三個整數n,m,t(2<=n,m<=20,t>0)。接下來的n行m列為地牢的地圖,其中包括:
. 代表路
* 代表牆
@ 代表ignatius的起始位置
^ 代表地牢的出口
a-j 代表帶鎖的門,對應的鑰匙分別為a-j
a-j 代表鑰匙,對應的門分別為a-j
每組測試資料之間有乙個空行。
輸出針對每組測試資料,如果可以成功逃亡,請輸出需要多少分鐘才能離開,如果不能則輸出-1。
但是,有10種鑰匙,這使維度處理變得困難(因為就算是開了10個維度記錄鑰匙也不能直接讓某個維度改變,因為c++裡就沒有這種操作)
所以使用狀態壓縮
把10把鑰匙的攜帶狀態用乙個二進位制的數字記錄下來(程式裡用10進製整形變數表示)
例:第0位記錄鑰匙a的攜帶狀態,0代表沒有,1代表有。以此類推。
這樣就可以帶著10把鑰匙的狀態進行搜尋了。
當遇到一把鑰匙時:找到鑰匙對應的位,然後和當前狀態取「位或」操作就相當於撿起了這把鑰匙
(位或:即按位取或,有1就得1,都不是1就得0)
例:當前狀態有鑰匙b,e;要撿起鑰匙j
所以當前的狀態:ab
cdef
ghij
0100
1000
00在程式裡就是18(2 ^ 1 + 2 ^ 4)
現在要撿起的鑰匙j就是512(其他位置都是0,第九位是1)ab
cdef
ghij
0000
0000
01兩個二進位制數字取位或之後ab
cdef
ghij
0100
1000
01這樣就算是撿起了鑰匙。
同理,當遇到門時,判斷是否有這個門對應的鑰匙時
算出門對應的二進位制數字,和當前狀態取「位與」操作後,看得數是否為零,為零就是沒有對應的鑰匙。
(位與:按位取「與」,都為1得1,否則為0)
關於廣搜:
先判斷當前狀態,再看能不能去,一定要有條理,否則會很亂。
並且廣搜第一次到乙個地方時一定是最小的步數(但深搜不是),所以再加個判斷就行了
#include #include #include using namespace std;
char a[25][25];
int n, m, t;
int f[25][25][2048];
int sx, sy;
int addx[5] = ;
int addy[5] = ;
struct point
;queue q;
int bfs()
if (((a[h.x][h.y] >= 'a' && a[h.x][h.y] <= 'z') || a[h.x][h.y] == '.' ||
(a[h.x][h.y] >= 'a' && a[h.x][h.y] <= 'j' && (h.state & (1 << (a[h.x][h.y] - 'a'))) != 0)) //是鑰匙 或者 路 或者 有對應鑰匙能開啟的門,但是一定要沒去過
&& f[h.x][h.y][h.state] == -1)
if (a[h.x][h.y] == '^')
if (f[g.x][g.y][g.state] + 1 < t)
return f[g.x][g.y][g.state] + 1;
else
return -1;}}
return -1;
}int main()
}cout << bfs() << endl;
}return 0;
}
杭電1429 勝利大逃亡 續
ignatius再次被魔王抓走了 搞不懂他咋這麼討魔王喜歡 這次魔王汲取了上次的教訓,把ignatius關在乙個n m的地牢裡,並在地牢的某些地方安裝了帶鎖的門,鑰匙藏在地牢另外的某些地方。剛開始ignatius被關在 sx,sy 的位置,離開地牢的門在 ex,ey 的位置。ignatius每分鐘只...
1429 勝利大逃亡( 續 ) hdu
ignatius再次被魔王抓走了 搞不懂他咋這麼討魔王喜歡 這次魔王汲取了上次的教訓,把ignatius關在乙個n m的地牢裡,並在地牢的某些地方安裝了帶鎖的門,鑰匙藏在地牢另外的某些地方。剛開始ignatius被關在 sx,sy 的位置,離開地牢的門在 ex,ey 的位置。ignatius每分鐘只...
HDU1429 勝利大逃亡 續
學習位壓縮很好的一道題,因為只有10把鑰匙,那麼可以把10鑰匙壓縮二進位制,比如1000就表示身上只要第4把鑰匙的狀態,110表示帶有第2把和第3把鑰匙,那麼要判斷當前的鑰匙串有沒有能開啟當前門鑰匙,那麼就只要乙個 運算就可以,因為11101110 00100000 00100000 這樣就說明那一...