这道题是典型的bfs广搜问题先简单说下思路
1.先对幼儿园进行搜索,得到每个点着火的时间并存入数组。
2.对人员初始位置进行搜索,枚举出所有可能的路线得到最短时间
这道题的思路并不难想,但是有两点容易被忽略
1,墙壁的阻断效果只对人员有效,但是对于火焰无效
2,尤其注意“两人这一秒行动完之后,火势才蔓延开”,这是很重要的点,我就是对这句理解不透彻导致案例通过0%,这句话的真正意义在于,假设人员到达地点(x,y)的时间为t1,火焰到达的时间为t2,如果此地不是出口,那么必须严格满足t1<t2两人才可以进入此地,而如果此地是出口,只需要满足t1<=t2即可,我们可以这样来理解,当两人进入某地行动完成后,火焰再开始行动,虽然是同一时间,但是有先后顺序,比如两人可以在第四秒进入地点A,但是因为火焰第四秒也会到,两人到了地点A后只能坐以待毙等第五秒到来,可是火来的更快,那么就不能进来,来了就G。而如果地点A是出口就不一样了,两人在第四秒进入地点A后行为没有完成,还要开门润出去,这时候两人行动才算结束。火来了也拦不住他们了。
以下是ac代码
#include<iostream> #include<queue> struct node { int x, y,time; }; using namespace std; queue<node> que; const int N = 40; int h[N][N],hh[N][N], t, MIN,n, m, res, a[8]={-1,1,0,0,-1,-1,1,1},b[8]={0,0,-1,1,-1,1,-1,1}; char ch[N][N]; void han(int x,int y) { queue<node> qu; node t; t.x = x, t.y = y, t.time = 0; qu.push(t); hh[x][y] = 0; while (qu.size()) { node tt = qu.front(); for (int i = 0; i <= 7; i++) { t.x = tt.x + a[i],t.y=tt.y+b[i],t.time=tt.time+1; if (t.x >= 1 && t.x <= n && t.y >= 1 && t.y <= m && hh[t.x][t.y] == -1) { hh[t.x][t.y] = t.time; qu.push(t); } } qu.pop(); } return; } bool bfs() { while (que.size()) { node tt = que.front(); for (int i = 0; i <= 3; i++) { node t; t.x = tt.x + a[i], t.y = tt.y + b[i], t.time = tt.time + 1; if (t.x >= 1 && t.x <= n && t.y >= 1 && t.y <= m && !h[t.x][t.y] && t.time <= hh[t.x][t.y] && ch[t.x][t.y] != '#') { if (ch[t.x][t.y] == 'E') { res = t.time; while (que.size()) que.pop(); return 1; } if (t.time < hh[t.x][t.y]) { h[t.x][t.y] = 1; que.push(t); } } } que.pop(); } return 0; } int main() { cin >> t; while (t--) { res = 0; cin >> n >> m; for (int i = 0; i <N; i++) for (int j = 0; j < N; j++) { h[i][j] = 0; hh[i][j] = -1; } for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) { cin >> ch[i][j]; if (ch[i][j] == '*')//火灾发源地 han(i, j); else if (ch[i][j] == 'S')//人员位置 { h[i][j] = 1; node t; t.x = i, t.y = j, t.time = 0; que.push(t); } } if (bfs()) cout << res << endl; else cout << "T_T" << endl; } }
这是我这个菜狗的第一篇题解,希望能对大家有所帮助,写的不好大家轻喷。
"