这道题是典型的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;
}
}
这是我这个菜狗的第一篇题解,希望能对大家有所帮助,写的不好大家轻喷。
"

京公网安备 11010502036488号