description
ignatius再次被魔王抓走了(搞不懂他咋這麼討魔王喜歡)……
這次魔王汲取了上次的教訓,把ignatius關在乙個n*m的地牢裡,並在地牢的某些地方安裝了帶鎖的門,鑰匙藏在地牢另外的某些地方。剛開始ignatius被關在(sx,sy)的位置,離開地牢的門在(ex,ey)的位置。ignatius每分鐘只能從乙個座標走到相鄰四個座標中的其中乙個。魔王每t分鐘回地牢視察一次,若發現ignatius不在原位置便把他拎回去。經過若干次的嘗試,ignatius已畫出整個地牢的地圖。現在請你幫他計算能否再次成功逃亡。只要在魔王下次視察之前走到出口就算離開地牢,如果魔王回來的時候剛好走到出口或還未到出口都算逃亡失敗。
input
每組測試資料的第一行有三個整數n,m,t(2<=n,m<=20,t>0)。接下來的n行m列為地牢的地圖,其中包括:
. 代表路
* 代表牆
@ 代表ignatius的起始位置
^ 代表地牢的出口
a-j 代表帶鎖的門,對應的鑰匙分別為a-j
a-j 代表鑰匙,對應的門分別為a-j
每組測試資料之間有乙個空行。
output
針對每組測試資料,如果可以成功逃亡,請輸出需要多少分鐘才能離開,如果不能則輸出-1。
sample input
4 5 17@a.b.
a*.*.
*..*^
c..b*
4 5 16
@a.b.
a*.*.
*..*^
c..b*
sample output
16-1
bfs搜尋。每分鐘走一格,且在魔王回來前逃到大門處算作逃跑成功,即從起點到終點的最少步數小於t即可。即使是等於t,也是失敗的。在迷宮中求起點到終點的最少步數,很容易便想到bfs。而此題中,想要通過門,必須要有對應的鑰匙,所以是有可能為了取鑰匙開門,而在乙個格仔上走過好幾次。因此,寫標記格仔是否走過的vis陣列時,可以認為通過同乙個格仔時如果攜帶的鑰匙不同,可以認為是不同的通過方式。因此,可以將vis陣列設為三維陣列,前兩維表示格仔,第三維通過位運算來表示攜帶鑰匙的情況。最多有十柄鑰匙,因此攜帶鑰匙的情況最多有2^10=1024種。
#include #include #include #include using namespace std;
struct node
;int dir[4][2]=;
int vis[21][21][1025];
int map[21][21];
int n,m,t;
int bfs(int sti,int stj)
}else if (map[next.x][next.y]>='a'&&map[next.x][next.y]<='z')
else}}
return -1;
}int main()
{ while(scanf("%d%d%d",&n,&m,&t)==3)
{int sti=0,stj=0;
char w=getchar();
memset(vis,0,sizeof(vis));
for(int i=0;i
HDU1429 勝利大逃亡 續
學習位壓縮很好的一道題,因為只有10把鑰匙,那麼可以把10鑰匙壓縮二進位制,比如1000就表示身上只要第4把鑰匙的狀態,110表示帶有第2把和第3把鑰匙,那麼要判斷當前的鑰匙串有沒有能開啟當前門鑰匙,那麼就只要乙個 運算就可以,因為11101110 00100000 00100000 這樣就說明那一...
hdu 1429 勝利大逃亡 續
code include include using namespace std struct px struct px start char map 25 25 int mark 25 25 1025 dir 4 2 三維表,走過的路徑對應表的狀態 int wys 10 int n,m,t boo...
hdu 1429勝利大逃亡 續
題目 一開始想了好幾種方法。最後實驗都錯了。要麼是就是演算法思想錯誤。然後以為可以這樣。果斷。記憶體超出。下面是錯誤 include include includeusing namespace std define n 21 int n,m,t char map n n bool visited ...