【思路】
题目中的“可以沿直线发射打破砖墙”可能会迷惑到很多人,实际上可以等价理解为“通过砖墙的时间为2个单位”,这样题目就迎刃而解了。第一次碰到时可能不能很好把握,第二次基本就可以当作水题了。
【错误点】
1.不能用裸的bfs。广搜的实际思想是将到达时间最短的放在队首,这样首次到达终点即为时间的最小值。通过砖墙的时间为两个单位,通过砖墙后可能不是时间最小值。用优先队列可以解决这一问题。
2.c++中memset初始化为memset(vis,0,sizeof(vis)),很多人可能会写成memset(vis,sizeof(vis),0)。
1 #include<iostream> 2 #include<cstdio> 3 #include<iostream> 4 #include<queue> 5 using namespace std; 6 const int MAXN=300+5; 7 struct rec 8 { 9 int x,y,cost; 10 bool operator < (const rec &x) const 11 { 12 return (cost > x.cost); 13 } 14 }; 15 char map[MAXN][MAXN]; 16 int m,n,yx,yy; 17 18 void init() 19 { 20 getchar(); 21 for (int i=0;i<m;i++) 22 { 23 for (int j=0;j<n;j++) 24 { 25 scanf("%c",&map[i][j]); 26 if (map[i][j]=='Y') 27 { 28 yx=i;yy=j; 29 } 30 } 31 getchar(); 32 } 33 } 34 35 int bfs() 36 { 37 int vis[MAXN][MAXN]; 38 int dx[4]={0,0,1,-1}; 39 int dy[4]={1,-1,0,0}; 40 priority_queue<rec> que; 41 memset(vis,0,sizeof(vis)); 42 vis[yx][yy]=1; 43 rec now; 44 now.x=yx;now.y=yy;now.cost=0; 45 que.push(now); 46 while (!que.empty()) 47 { 48 rec head=que.top(); 49 if (map[head.x][head.y]=='T') return(head.cost); 50 que.pop(); 51 for (int i=0;i<4;i++) 52 { 53 int tempx=head.x+dx[i],tempy=head.y+dy[i]; 54 if (tempx<0||tempx>=m||tempy<0||tempy>=n||map[tempx][tempy]=='R'||map[tempx][tempy]=='S'||vis[tempx][tempy]) continue; 55 vis[tempx][tempy]=1; 56 now.x=tempx;now.y=tempy; 57 now.cost=head.cost+1; 58 if (map[tempx][tempy]=='B') now.cost++; 59 que.push(now); 60 } 61 } 62 return(-1); 63 } 64 65 int main() 66 { 67 while (scanf("%d%d",&m,&n)!=EOF) 68 { 69 if (m==n && n==0) break; 70 init(); 71 cout<<bfs()<<endl; 72 } 73 return 0; 74 }