hdu 杭電1429 勝利大逃亡 續

2021-09-13 10:47:22 字數 2237 閱讀 5306

題目表述

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 這樣就說明那一...