
题意:在n*m的网格内,有一个人和n堆火,人可以往上下左右四个方向走,同时所有的火也会想四周蔓延,问你人可不可以在火包围他之前逃离这个n*m的范围。
思路:问人可不可以逃离这个范围,就是看人能不能走到最外面的一圈的格子。但是人在走的时候火也会走,那么我们就要进行人 和火的同时的bfs,人和火同时bfs同时更新状态,首先对于人,人先往四周bfs,但是问题来了,我们怎么判断什么时候这一轮人的bfs应该停止去进行火的bfs——————我们可以在每次bfs之前去记录队列中包含的元素,只要对队列的元素进行 bfs就可以停止了,之后对火的bfs就可以了。但是有个问题需要注意一下,就是当人的bfs之后,火可能会把人能走的位置直接封住,但是人的可能的情况已经进入队列了,我们再删除也不好处理,那么我们可以逆向思维先bfs火的范围的,因为火如果先走的话那么人直接走能走的点就可以了
那么最后的整体的框架就是:
先bfs火能走的范围
然后bfs人能走的范围
每次bfs的次数是bfs之前队列的元素的个数
注意最后到达最外圈的结果应该要+1才能出去
最后我bfs的标记写错了,我的每次标记时是在出队的时候再标记
但是正确的标记应该是在入队的时候就去标记,因为如果是在出队时才标记,那么可能会标记很多重复的元素导致t(比如我入队了{1,2,3}三个元素,然后到1这个元素的时候也可能会入队{2,3}这两个元素,而先标记1 2 3三个元素在之后就不会出现重复入队的情况),当时就卡了这个点qwq!!!
代码
- /**
- * ┏┓ ┏┓+ +
- * ┏┛┻━━━┛┻┓ + +
- * ┃ ┃
- * ┃ ━ ┃ ++ + + +
- * ████━████+
- * ◥██◤ ◥██◤ +
- * ┃ ┻ ┃
- * ┃ ┃ + +
- * ┗━┓ ┏━┛
- * ┃ ┃ + + + +Code is far away from
- * ┃ ┃ + bug with the animal protecting
- * ┃ ┗━━━┓ 神兽保佑,代码无bug
- * ┃ ┣┓
- * ┃ ┏┛
- * ┗┓┓┏━┳┓┏┛ + + + +
- * ┃┫┫ ┃┫┫
- * ┗┻┛ ┗┻┛+ + + +
- */
-
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #define sc_int(x) scanf("%d", &x)
- #define sc_ll(x) scanf("%lld", &x)
- #define pr_ll(x) printf("%lld", x)
- #define pr_ll_n(x) printf("%lld\n", x)
- #define pr_int_n(x) printf("%d\n", x)
- #define ll long long
- using namespace std;
-
- const int N = 1000000 + 100;
- int n, m, h;
- ll s[N];
- char Map[1010][1010];
-
- struct lk
- {
- int x;
- int y;
- int cnt;
- };
- queue
q, p; - int dirx[5] = {0, 1, 0, -1, 0};
- int diry[5] = {0, 0, -1, 0, 1};
- bool st[1010][1010];
- bool stf[1010][1010];
-
- void bfs(int a, int b)
- {
-
- q.push({a, b, 0});
- st[a][b] = 1;
- int sum=0;
- while (q.size() )
- {
- while (p.size())
- {
-
- lk kk = p.front();
- if (kk.cnt > sum)
- break;
- p.pop();
-
- // cout<
- for (int i = 1; i <= 4; i++)
- {
- int xx = kk.x + dirx[i], yy = kk.y + diry[i];
-
- if (xx < 1 || xx > n || yy < 1 || yy > m)
- continue;
- if ( Map[xx][yy] != '.')
- continue;
- // cout<
- Map[xx][yy]='F';
- p.push({xx, yy, kk.cnt + 1});
- }
- }
-
- while (q.size())
- {
- lk k = q.front();
- if(k.cnt>sum)break;
- q.pop();
-
- // cout<
- if (k.x == 1 || k.x == n || k.y == 1 || k.y == m)
- {
- cout << k.cnt+1 << endl;
- return;
- }
-
-
- for (int i = 1; i <= 4; i++)
- {
- int xx = k.x + dirx[i], yy = k.y + diry[i];
- if (xx < 1 || xx > n || yy < 1 || yy > m)
- continue;
- if (st[xx][yy] || Map[xx][yy] == '#'||Map[xx][yy]=='F')
- continue;
- st[xx][yy] = 1;
- q.push({xx, yy, k.cnt + 1});
- }
- }
-
- sum++;
- }
-
- cout << "IMPOSSIBLE\n";
- return;
- }
-
- int main()
- {
- int t;
- sc_int(t);
- while (t--)
- {
- memset(st,0,sizeof st);
-
- while(q.size())q.pop();
- while(p.size())p.pop();
- int x, y;
- cin >> n >> m;
- for (int i = 1; i <= n; i++)
- cin >> Map[i] + 1;
- for (int i = 1; i <= n; i++)
- {
- for (int j = 1; j <= m; j++)
- {
- if (Map[i][j] == 'F')
- {
- p.push({i, j, 0});
- stf[i][j] = 1;
- }
- if (Map[i][j] == 'J')
- {
- x = i;
- y = j;
- }
- }
- }
- bfs(x, y);
- }
-
- return 0;
- }