HDU 1429 胜利大逃亡(续) (BFS+位压缩)
生活随笔
收集整理的這篇文章主要介紹了
HDU 1429 胜利大逃亡(续) (BFS+位压缩)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1429
?
勝利大逃亡(續)
Time Limit: 4000/2000 MS (Java/Others)????Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3309????Accepted Submission(s): 1063
Problem 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 Author LL Source ACM暑期集訓隊練習賽(三) Recommend linle 這題很糾結。。。。想了好幾天了。。。。一開始想到以每個點是否走過超過2次作為判斷條件,調試的時候發現這種方法顯然錯誤,后來又想到在結構體中加入存儲鑰匙的數組,可惜測試用例都過不了,后來想想,就算過了測試用例也應該會MLE的吧,貌似很復雜。。。。實在沒辦法了,只能找找題解了,看到有大牛介紹的位壓縮方法。。。果斷用上了,經過多次的WA后,終于A過。。。還得繼續努力啊!加油! 思路: 用一個十位的二進制數表示鑰匙,如00000000001代表有第一個鑰匙,0000000010代表第二個鑰匙。 因為有10把鑰匙,因此有2^10=1024種情況,可以用一個三維數組標記。 如果該點為鑰匙點,則可采用|運算來模擬拾取,顯然0001 | 1000 = 1001 當為相應的門時采用&運算來模擬開啟,例如1101 & 0001 = 0001(即可以打開'A'門) Code
1 #include<cstdio> 2 #include<iostream> 3 #include<queue> 4 #include<cstring> 5 using namespace std; 6 #define N 24 7 struct node 8 { 9 int x; 10 int y; 11 int time; 12 int key; 13 }; 14 char g[N][N]; 15 int dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}}; 16 int n,m,t,sx,sy,ex,ey; 17 int vis[N][N][1030]; 18 void getd() 19 { 20 int i,j; 21 char s[N]; 22 for(i=0;i<n;i++) 23 { 24 gets(s); 25 for(j=0;j<strlen(s);j++) 26 { 27 g[i][j]=s[j]; 28 if(s[j]=='@') 29 { 30 sx=i;//起點 31 sy=j; 32 } 33 else if(s[j]=='^') 34 { 35 ex=i;//終點 36 ey=j; 37 } 38 } 39 } 40 } 41 void bfs() 42 { 43 queue<node>q; 44 memset(vis,0,sizeof(vis)); 45 node p,s; 46 int i,j,key; 47 p.x=sx;p.y=sy; 48 p.time=p.key=0; 49 vis[p.x][p.y][p.key]=1; 50 q.push(p); 51 while(!q.empty()) 52 { 53 p=q.front(); 54 q.pop(); 55 for(i=0;i<4;i++) 56 { 57 s.x=p.x+dir[i][0]; 58 s.y=p.y+dir[i][1]; 59 s.key=p.key; 60 s.time=p.time+1; 61 if(!(s.x>=0&&s.x<n&&s.y>=0&&s.y<m)||g[s.x][s.y]=='*'||s.time>t)continue; 62 if(g[s.x][s.y]=='^'&&s.time<t){printf("%d\n",s.time);return ;}//已到達終點位置 63 if(g[s.x][s.y]>='a'&&g[s.x][s.y]<='z') 64 { 65 key=1<<(g[s.x][s.y]-'a'); 66 s.key|=key;//加入鑰匙 67 } 68 else if(g[s.x][s.y]>='A'&&g[s.x][s.y]<='Z') 69 { 70 key=1<<(g[s.x][s.y]-'A'); 71 if(!(key&s.key))continue;//沒有鑰匙,無法打開門 72 } 73 if(vis[s.x][s.y][s.key])continue;//已經經歷過該狀態,不可再經歷 74 vis[s.x][s.y][s.key]=1;//標記 75 q.push(s); 76 } 77 } 78 printf("-1\n"); 79 } 80 int main() 81 { 82 while(scanf("%d %d %d",&n,&m,&t)!=EOF) 83 { 84 getchar(); 85 getd(); 86 bfs(); 87 } 88 return 0; 89 }
?
轉載于:https://www.cnblogs.com/lfeng/archive/2013/04/04/2999223.html
總結
以上是生活随笔為你收集整理的HDU 1429 胜利大逃亡(续) (BFS+位压缩)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 输卵管堵塞一般多久能治好
- 下一篇: .net实现跨页面传值