题意:图中头几堆火,火是按四周蔓延的,然后判断J只能走‘.’,而且要在火蔓延之前才能通过,然后如果J在图的边界,那么就逃出了;
思路:对火堆进行BFS,得到火到达各个'.'的最短的时间,然后对J进行BFS,要在火到达之前进行通过;
注意:因为BFS的性质,先到达的就是最短的时间,然后对于没用火到达的地方,不用判断火的时间,防止因为初始化times数组使得时间一样引发错误;
说明:思路很好想到,然而刚开始我是遇到一个‘F’进行一次BFS,导致TLE,正解是把所有的F压到一个队列中,然后一次BFS就行了;
TLE代码:
#include<iostream>
#include<cstdio>
#include<queue>
#include<stack>
#include<cstring>
using namespace std;
typedef long long ll;
const int maxn = 1000 + 10;
char s[maxn][maxn];
bool vis[maxn][maxn];
struct Node
{
int x;
int y;
int times;
}Y;
int derict[][2] =
{
1,0,
-1,0,
0,1,
0,-1
};
int timess[maxn][maxn];
bool viss[maxn][maxn];
int n,m;
void bfs1(int x,int y)
{
Node start;
start.x = x;
start.y = y;
start.times = 0;
viss[x][y] = true;
queue<Node>q;
q.push(start);
vis[x][y] = true;
while(!q.empty())
{
Node t = q.front();
q.pop();
for(int i = 0; i < 4; i ++)
{
Node ts;
ts.x = t.x + derict[i][0];
ts.y = t.y + derict[i][1];
ts.times = t.times + 1;
if(ts.x >= 0 && ts.x < n && ts.y >= 0 && ts.y < m && !vis[ts.x][ts.y] && s[ts.x][ts.y] != '#' )
{
viss[ts.x][ts.y] = true;
timess[ts.x][ts.y] = min(timess[ts.x][ts.y],ts.times);
q.push(ts);
vis[ts.x][ts.y] = true;
}
}
}
}
int bfs()
{
queue<Node>q;
q.push(Y);
vis[Y.x][Y.y] = true;
if(Y.x == 0 || Y.x == n -1 || Y.y == 0 || Y.y == m - 1)
{
return Y.times;
}
while(!q.empty())
{
Node t = q.front();
q.pop();
for(int i = 0; i < 4; i ++)
{
Node ts;
ts.x = t.x + derict[i][0];
ts.y = t.y + derict[i][1];
ts.times = t.times + 1;
if(ts.x >= 0 && ts.x < n && ts.y >= 0 && ts.y < m && !vis[ts.x][ts.y] && s[ts.x][ts.y] != '#' && s[ts.x][ts.y] != 'J')
{
if(viss[ts.x][ts.y])
{
if(ts.times < timess[ts.x][ts.y])
{
if(ts.x == 0 || ts.x == n -1 || ts.y == 0 || ts.y == m - 1)
{
return ts.times;
}
q.push(ts);
vis[ts.x][ts.y] = true;
}
}
else
{
if(ts.x == 0 || ts.x == n -1 || ts.y == 0 || ts.y == m - 1)
{
return ts.times;
}
q.push(ts);
vis[ts.x][ts.y] = true;
}
}
}
}
return -1;
}
int main()
{
int Tcase;
scanf("%d",&Tcase);
for(int ii = 1; ii <= Tcase ; ii ++)
{
memset(viss,false,sizeof(viss));
memset(vis,false,sizeof(vis));
scanf("%d%d",&n,&m);
for(int i = 0; i < n ; i ++)
{
for(int j = 0; j < m ; j ++)
{
timess[i][j] = maxn*maxn;
}
}
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] == 'J')
{
Y.x = i;
Y.y = j;
Y.times = 0;
}
if(s[i][j] == 'F')
{
memset(vis,false,sizeof(vis));
bfs1(i,j);
}
}
}
// for(int i = 0; i < n ; i ++)
// {
// for(int j = 0; j < m ; j ++)
// {
// cout << time[i][j] << " ";
// }
// cout << endl;
// }
memset(vis,false,sizeof(vis));
int ans = bfs();
if(ans == -1)
{
cout << "IMPOSSIBLE" << endl;
continue;
}
cout << ans + 1 << endl;
}
return 0;
}
AC代码:
#include<iostream>
#include<cstdio>
#include<queue>
#include<stack>
#include<cstring>
using namespace std;
typedef long long ll;
const int maxn = 1000 + 10;
#define INF 0x3f3f3f3f
char s[maxn][maxn];
struct Node
{
int x;
int y;
int s;
}J;
int derict[][2]=
{
-1,0,
1,0,
0,1,
0,-1
};
queue<Node>Q;
int n,m;
bool vis[maxn][maxn];
bool viss[maxn][maxn];
int times[maxn][maxn];
void Init()
{
memset(times,INF,sizeof(times));
while(!Q.empty())
{
Node t = Q.front();
Q.pop();
times[t.x][t.y] = t.s;
vis[t.x][t.y] = true;
for(int i = 0; i < 4; i ++)
{
Node ts;
ts.x = t.x + derict[i][0];
ts.y = t.y + derict[i][1];
ts.s = t.s + 1;
if(ts.x >= 0 && ts.x < n && ts.y >= 0 && ts.y < m && !vis[ts.x][ts.y] && s[ts.x][ts.y]!= '#')
{
vis[ts.x][ts.y] = true;
Q.push(ts);
}
}
}
// for(int i = 0; i < n; i ++)
// {
// for(int j = 0; j < m; j ++)
// {
// cout << times[i][j] << " ";
// }
// cout << endl;
// }
}
int bfs()
{
memset(vis,false,sizeof(vis));
memset(viss,false,sizeof(viss));
Init();
queue<Node>q;
q.push(J);
viss[J.x][J.y] = true;
while(!q.empty())
{
Node t = q.front();
q.pop();
if(t.x == 0 || t.x == n - 1 || t.y == 0 || t.y == m - 1)
{
return t.s + 1;
}
for(int i = 0; i < 4; i ++)
{
Node ts;
ts.x = t.x + derict[i][0];
ts.y = t.y + derict[i][1];
ts.s = t.s + 1;
if(ts.x >= 0 && ts.x < n && ts.y >= 0 && ts.y < m && !viss[ts.x][ts.y] && s[ts.x][ts.y] != '#' && s[ts.x][ts.y] != 'F' && ((vis[ts.x][ts.y] && ts.s < times[ts.x][ts.y])||(!vis[ts.x][ts.y])))
{
q.push(ts);
viss[ts.x][ts.y] = true;
}
}
}
return -1;
}
int main()
{
int Tcase;
scanf("%d",&Tcase);
for(int ii = 1; ii <= Tcase; ii ++)
{
while(!Q.empty())
{
Q.pop();
}
scanf("%d%d",&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] == 'J')
{
J.x = i;
J.y = j;
J.s = 0;
}
if(s[i][j] == 'F')
{
Node k;
k.x = i;
k.y = j;
k.s = 0;
Q.push(k);
}
}
}
int ans = bfs();
if(ans == -1)
{
cout << "IMPOSSIBLE" << endl;
}
else cout << ans << endl;
}
return 0;
}