这道题在传统的走迷宫问题上面加了门和钥匙, 那我们在加一个状态表示他目前所携带的钥匙即可。。代码如下:
wa点:1.在用钥匙打开门后钥匙还是可以继续带在身上的 2:判断一个状态某一位我1是(st>>num)&1 == 1..不要搞错了啊
#include <cstdio> #include <algorithm> #include <cstring> #include <queue> using namespace std; int n, m, t; char map[50][50]; int sx, sy, ex, ey; int vis[21][21][1027]; int dx[] = {1, -1, 0, 0}; int dy[] = {0, 0, 1, -1}; bool inside(int x, int y) { return x>=0&&x<n&&y>=0&&y<m; } struct state { int x, y, steps; int st; state() {} state(int x, int y, int steps, int st):x(x), y(y), steps(steps), st(st) {} }; void debug(state tp) { printf("(x, y)=(%d, %d), steps=%d, state=%d ", tp.x, tp.y, tp.steps, tp.st); } queue<state> que; int bfs() { memset(vis, 0, sizeof(vis)); while(!que.empty()) que.pop(); que.push(state(sx, sy, 0, 0)); vis[sx][sy][0] = 1; while(!que.empty()) { state tp = que.front(); que.pop(); //printf("POP: "); //debug(tp); if(tp.x==ex && tp.y==ey) return tp.steps; /*if(tp.x==1&&tp.y==3&&tp.steps==6&&tp.st==2) { int tp; tp = 2; }*/ for(int i=0; i<4; i++) { int nx = tp.x + dx[i], ny = tp.y + dy[i], steps = tp.steps; int nowstate = tp.st; if(!inside(nx, ny)) continue; if(map[nx][ny]=='.' && !vis[nx][ny][nowstate]) { que.push(state(nx, ny, steps+1, nowstate)); vis[nx][ny][nowstate] = 1; //printf(" push: "); //debug(state(nx, ny, steps+1, nowstate)); } else if(map[nx][ny] == '*') //遇到了墙 continue; else if(map[nx][ny]>='A' && map[nx][ny]<='J') //遇到了门 { int num = map[nx][ny] - 'A'; if(((nowstate>>num)&1) == 1 && !vis[nx][ny][nowstate]) //可以打开 { que.push(state(nx, ny, steps+1, nowstate)); vis[nx][ny][nowstate] = 1; //printf(" push: "); //debug(state(nx, ny, steps+1, nowstate^(1<<num))); } } else if(map[nx][ny]>='a' && map[nx][ny]<='j') { int num = map[nx][ny] - 'a'; if(!vis[nx][ny][nowstate|(1<<num)]) { que.push(state(nx, ny, steps+1, nowstate|(1<<num))); vis[nx][ny][nowstate|(1<<num)] = 1; //printf(" push: "); //debug(state(nx, ny, steps+1, nowstate|(1<<num))); } } } } return -1; } int main() { while(scanf("%d%d%d", &n, &m, &t) == 3) { for(int i=0; i<n; i++) { scanf("%s", map[i]); for(int j=0; j<m; j++) if(map[i][j] == '@') { sx=i, sy=j; map[i][j] = '.'; } else if(map[i][j] == '^') { ex=i, ey=j; map[i][j] = '.'; } } int num = bfs(); if(num>=0 && num<t) printf("%d ", num); else printf("-1 "); } return 0; }