做这个题的时候我给想简单了,还以为是个基础的广搜,后来发现搜索无法完成,因为vis的标记已经不能再使用了,因为一旦标记了,同一个结点不能走两次,而题目中有的时候有些点必须要走两次,甚至多次.
我就无从下手了,赛后看了题解才知道,每个点都有16个状态,用状态压缩可以来保存每个点的钥匙状态,开一个三维的vis数组就可以了,然后这就变成了普通的bfs...代码如下.
还有就是,在一开始的时候我把状态记录错了,我竟然把|8写成了|16...给我整的一头雾水,后来才发现原来竟然是这里出错了..
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; /// b y r g /// 1 2 3 4 /// 1 2 4 8 int n,m,vis[110][110][16],go[4][2] = {1,0,-1,0,0,1,0,-1}; char maps[110][110]; struct Pos { int x,y,step,state; friend bool operator < (const Pos &a,const Pos &b) { return a.step > b.step; } }; priority_queue<Pos> que; Pos st,ex; bool OK1(int x,int y) { if(x>=0&&x<n&&y>=0&&y<m&&maps[x][y]!='#') return true; return false; } bool OK2(int i,int j,int s) { if(maps[i][j]=='B'&&(s&1)) return true; if(maps[i][j]=='Y'&&(s&2)) return true; if(maps[i][j]=='R'&&(s&4)) return true; if(maps[i][j]=='G'&&(s&8)) return true; return false; } int bfs(Pos a) { memset(vis,0,sizeof(vis)); vis[a.x][a.y][a.state] = 1; while(!que.empty()) que.pop(); que.push(a); while(!que.empty()) { Pos now = que.top(); que.pop(); Pos nxt; for(int k = 0; k < 4; k++) { int i = now.x + go[k][0]; int j = now.y + go[k][1]; if(OK1(i,j)) { if(OK2(i,j,now.state)&&!vis[i][j][now.state]) { vis[i][j][now.state]=1; nxt.step = now.step + 1; nxt.state = now.state; nxt.x = i,nxt.y = j; que.push(nxt); } else if(maps[i][j]=='b'&&!vis[i][j][now.state|1]) { vis[i][j][now.state|1] = 1; nxt.step = now.step + 1; nxt.state = now.state|1; nxt.x = i,nxt.y = j; que.push(nxt); } else if(maps[i][j]=='y'&&!vis[i][j][now.state|2]) { vis[i][j][now.state|2]=1; nxt.step = now.step + 1; nxt.state = now.state|2; nxt.x = i,nxt.y = j; que.push(nxt); } else if(maps[i][j]=='r'&&!vis[i][j][now.state|4]) { vis[i][j][now.state|4]=1; nxt.step = now.step + 1; nxt.state = now.state|4; nxt.x = i,nxt.y = j; que.push(nxt); } else if(maps[i][j]=='g'&&!vis[i][j][now.state|8]) { vis[i][j][now.state|8]=1; nxt.step = now.step + 1; nxt.state = now.state|8; nxt.x = i,nxt.y = j; que.push(nxt); } else if(maps[i][j]=='.'&&!vis[i][j][now.state]) { vis[i][j][now.state]=1; nxt.step = now.step + 1; nxt.state = now.state; nxt.x = i,nxt.y = j; que.push(nxt); } else if(maps[i][j]=='X') return now.step+1; } } } return -1; } int main() { while(~scanf("%d%d",&n,&m)) { if(n == 0 && m == 0) break; for(int i = 0; i < n; i++) scanf("%s",maps[i]); ex.x = -1; for(int i = 0; i < n; i++) { for(int j = 0; j < m; j++) { if(maps[i][j] == '*') { st.x = i,st.y = j; st.step = 0,st.state = 0; } if(maps[i][j] == 'X') { ex.x = i,ex.y = j; ex.step = 0,ex.state = 0; } } } if(ex.x == -1) { puts("The poor student is trapped!"); continue; } maps[st.x][st.y] = '.'; int ans = bfs(st); if(ans == -1) puts("The poor student is trapped!"); else printf("Escape possible in %d steps.\n",ans); } return 0; }