hdu 1885 Key Task(bfs+位运算)
题意:矩阵中'#'表示墙,'.'表示通路,要求从起点'*'到达终点'X',途中可能遇到一些门(大写字母),要想经过,必须有对应的钥匙(小写字母)。问能否完成,若能,花费的时间是多少。
分析:同hdu 1429,只不过这里用map把四种钥匙标号了,否则爆内存。
错误:判断门的条件用 isupper(ch) 表示,所以终点'X'也在这个范围内。
1 #include<cstdio> 2 #include<cstring> 3 #include<cctype> 4 #include<map> 5 #include<queue> 6 #include<algorithm> 7 using namespace std; 8 9 const int MAXN=111; 10 const int KEY=4; 11 12 map<char,int> mp; 13 14 15 int dir[4][2]={0,-1,0,1,-1,0,1,0}; 16 17 struct Node{ 18 int x,y,t,key; 19 Node(){} 20 Node(int _x,int _y,int _t,int _key):x(_x),y(_y),t(_t),key(_key){} 21 }; 22 23 char g[MAXN][MAXN]; 24 int mark[MAXN][MAXN][1<<KEY]; 25 queue<Node>q; 26 27 int n,m,T; 28 29 bool wall(int x,int y) 30 { 31 if(x<0||x>=n||y<0||y>=m) 32 return true; 33 if(g[x][y]=='#') 34 return true; 35 return false; 36 } 37 38 int bfs(int sx,int sy) 39 { 40 while(!q.empty()) 41 q.pop(); 42 43 memset(mark,0,sizeof(mark)); 44 mark[sx][sy][0]=1; 45 q.push(Node(sx,sy,0,0)); 46 while(!q.empty()) 47 { 48 Node e=q.front();q.pop(); 49 50 for(int i=0;i<4;i++) 51 { 52 int dx=e.x+dir[i][0]; 53 int dy=e.y+dir[i][1]; 54 int dt=e.t+1; 55 int dkey=e.key; 56 57 char ch=g[dx][dy]; 58 59 if(wall(dx,dy)) 60 continue; 61 if(mark[dx][dy][dkey]) 62 continue; 63 if(g[dx][dy]=='X') 64 return dt; 65 if(isupper(ch)&&!(dkey&(1<<mp[ch]))) 66 continue; 67 if(islower(ch)) 68 dkey=dkey|(1<<mp[ch]); 69 70 mark[dx][dy][dkey]=1; 71 q.push(Node(dx,dy,dt,dkey)); 72 } 73 } 74 return -1; 75 } 76 77 int main() 78 { 79 mp['B']=mp['b']=0; 80 mp['Y']=mp['y']=1; 81 mp['R']=mp['r']=2; 82 mp['G']=mp['g']=3; 83 while(~scanf("%d%d",&n,&m)) 84 { 85 if(!n&&!m) 86 return 0; 87 88 for(int i=0;i<n;i++) 89 scanf("%s",g[i]); 90 91 int sx,sy,ex,ey; 92 for(int i=0;i<n;i++) 93 for(int j=0;j<m;j++) 94 if(g[i][j]=='*'){ 95 sx=i; 96 sy=j; 97 g[i][j]='.'; 98 } 99 100 int ans=bfs(sx,sy); 101 if(ans==-1) 102 printf("The poor student is trapped!\n"); 103 else 104 printf("Escape possible in %d steps.\n",ans); 105 } 106 return 0; 107 }