BFS,细节
注意到达一处时,先更新状态,再判mapp。
边界啊~~但是貌似codeblocks可以自动无视越界。。
#include <cstdio> #include <cstring> #include <queue> #include <ctype.h> using namespace std; typedef struct point{ int x,y,key,step; }point; int movee [4][2] = {{1,0},{-1,0},{0,-1},{0,1}}; int main() { char laby[105][105]; int mapp[16][105][105]; int r,c; while(scanf("%d %d",&r,&c)&&(r+c)) { memset(mapp,0,sizeof(mapp)); //map用来排重,即是已走和未走两状态,至于墙或者门的限制,直接用原图即可! for(int i=0;i<r;i++) scanf("%s",laby[i]); point st; //如果走到一个地方,再往前走将遇到一个门,但没拿相应钥匙,其他的方向又不会立刻走出, //则这条路是错的。但是这种情况已经包含在同态同位中。 bool jmp = 0; for(int i=0;i<r&&!jmp;i++) for(int j=0;j<c;j++) { if(laby[i][j]=='*') { laby[i][j] = '.';//similate st.x = i; st.y = j; st.key = 0; st.step = 0; jmp = 1; break; } } jmp = 0; queue <point> q; if(!q.empty()) q.pop(); q.push(st); while(!q.empty()) { point p = q.front(); q.pop(); mapp[p.key][p.x][p.y] = 1; for(int i=0;i<4;i++) { int tx = p.x + movee[i][0]; int ty = p.y + movee[i][1]; if(tx<0||ty<0||tx>=r||ty>=c) continue;//只顾着考虑墙和钥匙的问题,却忽视了基本的边界判断!!! if(laby[tx][ty]=='#'||(mapp[p.key][tx][ty]&&(!islower(laby[tx][ty])))) continue;//不作为就是有作为。。判重 //如果是钥匙的话那就按照更新后的钥匙状态算!!! if(laby[tx][ty]=='.') { point tmp = {tx,ty,p.key,p.step+1}; q.push(tmp); mapp[tmp.key][tx][ty] = 1; } else if(laby[tx][ty]=='X') { printf("Escape possible in %d steps.\n",p.step+1); jmp = 1; break; } else if(islower(laby[tx][ty])) { int tkey; if(laby[tx][ty]=='b') tkey = 1; else if(laby[tx][ty]=='y') tkey = 1 << 1 ; else if(laby[tx][ty]=='r') tkey = 1 << 2 ; else if(laby[tx][ty]=='g') tkey = 1 << 3 ; tkey = tkey | p.key; if(mapp[tkey][tx][ty]) continue; point tmp = {tx,ty,tkey,p.step+1}; q.push(tmp); mapp[tmp.key][tx][ty] = 1; } else { bool can = 0; if(laby[tx][ty]=='B') {if(p.key&1) can = 1;} else if(laby[tx][ty]=='Y') {if(p.key&(1<<1)) can = 1;} else if(laby[tx][ty]=='R') {if(p.key&(1<<2)) can = 1;} else if(laby[tx][ty]=='G') {if(p.key&(1<<3)) can = 1;} if(can) { point tmp = {tx,ty,p.key,p.step+1}; q.push(tmp); mapp[tmp.key][tx][ty] = 1; } } } if(jmp) break; } if(!jmp) printf("The poor student is trapped!\n"); } return 0; }