先按照第一份代码的修改思路修改,然后输出结果,看看是否能够观察出问题,看不出来再看看 STD。

第一份

基本修改

x 和 y 是初始坐标,每次循环应该是基于该点扩展,代码写成了 +=,该错误在两处 BFS 中都有。

int x=u.first;
		int y=u.second;
		for(int i=0;i<4;i++)
		{
			x+=dx[i];
			y+=dy[i];

火源是 0 时刻的,理解为初始的地图状态:人、火、障碍物,0 时刻静止。

在 1 时刻开始蔓延。

f.push({f1,f2});
st[f1][f2]=1;

IMPOSSIBLE 应该是在 while 结束后才输出,表示不可能逃离,cnt 应该每次都手动清零,去掉全局变量 cnt。

入队操作放在了 return 之后无意义,此处应该是括号没括对。

修改正确后发现仍输出两个 IMPOSSIBLE

while(!j.empty())
	{
		cnt++;
		int t=j.size();	
		for(int i=0;i<t;i++)
		{
		MII u=j.front();
		j.pop();
		int x=u.first;
		int y=u.second;
		for(int i=0;i<4;i++)
		{
			x+=dx[i];
			y+=dy[i];
			if(mp[x][y]=='#'||mp[x][y]=='J') continue;
			if(mp[x][y]=='F'&&st[x][y]<=cnt) continue;
			if(x==0||y==0||x==r+1||y==c+1)
			{
				cout<<cnt<<"\n";
				return;
				j.push({x,y});
				mp[x][y]='J';
			}
		}
	}
	cout<<"IMPOSSIBLE\n";
	}

打表观察 BFS1 的结果。

bfs1();
for (int i = 1; i <= r; i++) {
  for (int j = 1; j <= c; j++) {
    cout << mp[i][j] << " \n"[j == c];
  }
}
for (int i = 1; i <= r; i++) {
  for (int j = 1; j <= c; j++) {
    cout << st[i][j] << " \n"[j == c];
  }
}
bfs2();

输出第一次 BFS 后地图的变化和时间,观察是否符合预期。

bfs1();
  for (int i = 1; i <= r; i++) {
    for (int j = 1; j <= c; j++) {
      cout << mp[i][j] << " \n"[j == c];
    }
  }
  for (int i = 1; i <= r; i++) {
    for (int j = 1; j <= c; j++) {
      cout << st[i][j] << " \n"[j == c];
    }
  }
  bfs2();
}

通过观察发现,每次输入后都被 reset() 清空了,所以火直接烧完整个地图。


STD

// #include <bits/stdc++.h>

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <deque>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <string>
#include <vector>
#define j1 fsdjklsdjfkl

using namespace std;
char mp[1010][1010];
int st[1010][1010];
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};

int n, r, c, j1, j2, f1, f2;

typedef pair<int, int> MII;

queue<MII> F;
queue<MII> J;

void reset()
{
  memset(mp, '\0', sizeof(mp));
  memset(st, 0, sizeof(st));
  while (!F.empty()) {
    F.pop();
  }
  while (!J.empty()) {
    J.pop();
  }
}
void bfs1()
{
  // F.push({f1, f2});
  while (!F.empty()) {
    MII u = F.front();
    F.pop();
    int nx = u.first;
    int ny = u.second;
    for (int i = 0; i < 4; i++) {
      int x = nx + dx[i];
      int y = ny + dy[i];
      if (x >= 1 && x <= r && y >= 1 && y <= c && mp[x][y] != '#' && mp[x][y] != 'F') {
        mp[x][y] = 'F';
        st[x][y] = st[u.first][u.second] + 1;
        F.push({x, y});
      }
    }
  }
}

void bfs2()
{
  J.push({j1, j2});
  int cnt = 0;
  while (!J.empty()) {
    cnt++;
    int t = J.size();
    for (int i = 0; i < t; i++) {
      MII u = J.front();
      J.pop();
      int nx = u.first;
      int ny = u.second;
      for (int i = 0; i < 4; i++) {
        int x = nx + dx[i];
        int y = ny + dy[i];
        if (mp[x][y] == '#' || mp[x][y] == 'J') {
          continue;
        }
        if (mp[x][y] == 'F' && st[x][y] <= cnt) {
          continue;
        }
        if (x == 0 || y == 0 || x == r + 1 || y == c + 1) {
          cout << cnt << "\n";
          return;
        }
        J.push({x, y});
        mp[x][y] = 'J';
      }
    }
  }
  cout << "IMPOSSIBLE\n";
}

int main()
{
  cin >> n;
  while (n--) {
    reset();
    cin >> r >> c;
    for (int i = 1; i <= r; i++) {
      for (int j = 1; j <= c; j++) {
        cin >> mp[i][j];
        if (mp[i][j] == 'J') {
          j1 = i;
          j2 = j;
        }
        if (mp[i][j] == 'F') {
          F.push({i, j});
        }
      }
    }
    bfs1();
    // for (int i = 1; i <= r; i++) {
    // for (int j = 1; j <= c; j++) {
    // cout << mp[i][j] << " \n"[j == c];
    // }
    // }
    // for (int i = 1; i <= r; i++) {
    // for (int j = 1; j <= c; j++) {
    // cout << st[i][j] << " \n"[j == c];
    // }
    // }
    bfs2();
  }
  return 0;
}