勝利大逃亡(續)
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3734 Accepted Submission(s): 1216
Problem DescriptionIgnatius再次被魔王抓走了(搞不懂他咋這麼討魔王喜歡)……
這次魔王汲取了上次的教訓,把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
HDU1429 題目連結:here
HDU1885 題目連結:here (與此題如出一轍)
BFS+狀態壓縮
用flag[x][y][key]標記已搜尋過的狀態,key的一個二進位位代表一種鑰匙,如果獲得了第 i 種鑰匙,就將key的第 i 位置為1,如果訪問有第 i 種鎖的地方則要求key的第 i 位為1;
#include<cstdio>#include<queue>#define N 24using namespace std;struct node{ int x,y,key,dist;};char map[N][N],str[N];int flag[N][N][1<<11],sx,sy,ans;int dx[4]={0,1,0,-1};int dy[4]={1,0,-1,0};queue<node> q;void bfs(void){ while(!q.empty()) q.pop(); node t,nt; t.x=sx; t.y=sy; t.key=0; t.dist=0; q.push(t); while(!q.empty()) { t=q.front(); q.pop(); //printf("search:%d %d %d\n",t.x,t.y,t.key); for(int i=0;i<4;i++) { nt.dist=t.dist+1; nt.key=t.key; nt.x=t.x+dx[i]; nt.y=t.y+dy[i]; if(map[nt.x][nt.y]=='^' && ans>nt.dist) { ans=nt.dist; return ; } else if('a'<=map[nt.x][nt.y] && map[nt.x][nt.y]<='z') { nt.key=t.key|(1<<(map[nt.x][nt.y]-'a')); } if(map[nt.x][nt.y]!='*' && flag[nt.x][nt.y][nt.key]==0 && nt.dist<ans) { flag[nt.x][nt.y][nt.key]=1; if('A'<=map[nt.x][nt.y] && map[nt.x][nt.y]<='Z') { if((nt.key&(1<<(map[nt.x][nt.y]-'A')))) q.push(nt); } else q.push(nt); } } }}int main(){ //freopen("1.in","r",stdin); int n,m,t; while(scanf("%d%d%d",&n,&m,&t)!=EOF) { for(int i=0;i<N;i++) { for(int j=0;j<N;j++) { map[i][j]='*'; memset(flag[i][j],0,sizeof(flag[i][j])); } } for(int i=1;i<=n;i++) { scanf("%s",str); for(int j=1;j<=m;j++) { map[i][j]=str[j-1]; if('@'==map[i][j]) sx=i,sy=j,map[i][j]='.'; } } ans=t; bfs(); if(ans<t) printf("%d\n",ans); else printf("-1\n"); } return 0;}