简单的BFS搜索题,之前直接用的队列wa了一发,仔细想想还是需要用优先队列的。 因为在打坏砖块之后,当前节点的step++了, 因为在代码中打坏砖块然后移动到砖块上,这两个操作我们给合并到了一起,并不属于同一层节点,因此BFS的最短路性质就被破坏了,因此用优先队列,始终让头结点是step最小的那个就行了。有点像QUT校赛的那一题。
【代码】
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<algorithm> #define M 30 using namespace std; char s[310][310]; bool vis[310][310]; struct node{ int x,y; int step; node(int x = 0,int y =0 ,int step= 0):x(x),y(y),step(step){}; bool operator < (const node &a)const{ return step > a.step; } }st,ed; int dx[4] = {0,0,-1,1}; int dy[4] = {1,-1,0,0};int n,m; int bfs(){ priority_queue<node>Q; Q.push(st); memset(vis,0,sizeof(vis)); while(!Q.empty()){ node now = Q.top(); Q.pop(); node nt; for(int i=0;i<4;i++){ nt.x = now.x + dx[i]; nt.y = now.y + dy[i]; nt.step = now.step + 1; if(nt.x >=0 && nt.x < n && nt.y>=0 && nt.y<m &&!vis[nt.x][nt.y] ){ if(s[nt.x][nt.y] == 'E'){ vis[nt.x][nt.y] = 1; Q.push(nt); } else if(s[nt.x][nt.y] == 'T'){ return nt.step; } else if(s[nt.x][nt.y] == 'B'){ nt.step++; // 队列中的step不同 //因而优先队列是正解 vis[nt.x][nt.y] = 1; Q.push(nt); } } } } return -1; } int main(){ while(scanf("%d%d",&n,&m)!=EOF &&(n || m)){ for(int i=0;i<n;i++) scanf("%s",s[i]); for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ if(s[i][j] == 'Y') st.x = i,st.y = j; else if(s[i][j] == 'T') ed.x = i,ed.y = j; } } st.step = 0; int ans = bfs(); printf("%d\n",ans); } return 0; }