先附上题目链接
这题做的有点迷茫,由于对时间复杂度的计算一直不是很熟练.这题最开始的想法用BFS的时候记录一下时间.当层数加深一层的时候就让火势先蔓延一次.用一个vector来存火焰格子即可(后面改用了自己实现的vector).但是TLE了好多发之后…放弃了这个方法.决定先预处理一下火势蔓延到各个方块的时间.只要当前时间比火势蔓延的时间小,就可以走,否则视为障碍物.如此就不会TLE了.但一时半会也没想出来我最先处理的方式有啥大方向上的错误…希望有大佬能帮我解答一下…
这是TLE的code:
#include <iostream>
#include <queue>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <stack>
#include <string.h>
#include <algorithm>
#include <set>
#include <vector>
using namespace std;
const int INF = 0x3f3f3f3f;
const int mn = 1e3 + 10;
typedef long long ll;
int n, m;
int cnt;
struct node {
int r, c, cost;
};
node J;
char maze[mn][mn];
bool vis[mn][mn];
int dr[4] = { 1,0,0,-1 };
int dc[4] = { 0,1,-1,0 };
node fire[mn*mn];
bool inside(int r, int c) {
if (r >= 0 && r < n && c >= 0 && c < m) return true;
return false;
}
int fireup(int r, int c) {
for (int i = 0; i < 4; ++i) {
int cr = r + dr[i], cc = c + dc[i];
if (inside(cr, cc)) {
if (maze[cr][cc] == '#') continue;
if(maze[cr][cc] == 'F') continue;
maze[cr][cc] = 'F';
node x;x.r=cr;x.c=cc;x.cost = 0;
fire[cnt++] = x;
}
}
return 0;
}
bool bfs() {
queue<node> q;
q.push(J);
vis[J.r][J.c] = 1;
if (cnt) {
int len = cnt;
for (int i = 0; i < len; ++i) fireup(fire[i].r, fire[i].c);
}
int last = 0;
while (!q.empty()) {
node cur = q.front();
q.pop();
if (cur.r == 0 || cur.c == 0 || cur.r == n - 1 || cur.c == m - 1) {
printf("%d\n",cur.cost+1);
return true;
}
if (cur.cost == last + 1 && cnt) {
int len = cnt;
last = cur.cost;
for (int i = 0; i < len; ++i) fireup(fire[i].r, fire[i].c);
}
for (int i = 0; i < 4; ++i) {
int nr = cur.r + dr[i], nc = cur.c + dc[i];
if (!inside(nr, nc)) continue;
if (maze[nr][nc] == '#') continue;
if (maze[nr][nc] == 'F') continue;
if (vis[nr][nc]) continue;
vis[nr][nc] = 1;
node x;x.r=nr;x.c=nc;x.cost = cur.cost+1;
q.push(x);
}
}
return false;
}
int main() {
int t;
scanf("%d",&t);
while (t--) {
scanf("%d%d",&n,&m);
cnt=0;
for (int i = 0; i < n; ++i) {
scanf("%s",maze[i]);
for (int j = 0; j < m; ++j) {
if (maze[i][j] == 'J') {
J.r=i;
J.c=j;
J.cost=0;
}
if (maze[i][j] == 'F') {
node x;x.r=i;x.c=j;x.cost = 0;
fire[cnt++] = x;
}
}
}
memset(vis, 0, sizeof(vis));
if(!bfs()) printf("IMPOSSIBLE\n");
}
return 0;
}
这是AC代码(因为是由上面代码魔改后的产物,所以还有不少优化的地方.以后再搞吧)
#include <iostream>
#include <queue>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <stack>
#include <string.h>
#include <algorithm>
#include <set>
#include <vector>
using namespace std;
const int INF = 0x3f3f3f3f;
const int mn = 1e3 + 10;
typedef long long ll;
int n, m;
int cnt;
struct node {
int r, c, cost;
};
node J;
char maze[mn][mn];
bool vis[mn][mn];
int firetime[mn][mn];
int dr[4] = { 1,0,0,-1 };
int dc[4] = { 0,1,-1,0 };
node fire[mn*mn];
bool inside(int r, int c) {
if (r >= 0 && r < n && c >= 0 && c < m) return true;
return false;
}
bool bfs() {
queue<node> q;
q.push(J);
vis[J.r][J.c] = 1;
while (!q.empty()) {
node cur = q.front();
q.pop();
if (cur.r == 0 || cur.c == 0 || cur.r == n - 1 || cur.c == m - 1) {
printf("%d\n",cur.cost+1);
return true;
}
for (int i = 0; i < 4; ++i) {
int nr = cur.r + dr[i], nc = cur.c + dc[i];
if (!inside(nr, nc)) continue;
if (maze[nr][nc] == '#') continue;
if (vis[nr][nc]) continue;
if(firetime[nr][nc] <= cur.cost+1) continue;
vis[nr][nc] = 1;
node x;x.r=nr;x.c=nc;x.cost = cur.cost+1;
q.push(x);
}
}
return false;
}
int main() {
int t;
scanf("%d",&t);
while (t--) {
scanf("%d%d",&n,&m);
cnt=0;
memset(firetime,0x3f,sizeof(firetime));
memset(vis,0,sizeof(vis));
for (int i = 0; i < n; ++i) {
scanf("%s",maze[i]);
for (int j = 0; j < m; ++j) {
if (maze[i][j] == 'J') {
J.r=i;
J.c=j;
J.cost=0;
}
if (maze[i][j] == 'F') {
node x;x.r=i;x.c=j;x.cost = 0;
fire[cnt++] = x;
vis[i][j] = 1;
firetime[i][j] = 0;
}
}
}
int len = cnt;
queue<node> q1;
for(int i=0;i<len;++i) q1.push(fire[i]);
while(!q1.empty()){
node cur = q1.front();
q1.pop();
for (int i = 0; i < 4; ++i) {
int cr = cur.r + dr[i], cc = cur.c + dc[i];
if (inside(cr, cc)) {
if (maze[cr][cc] == '#') continue;
if(vis[cr][cc]) continue;
vis[cr][cc] = 1;
node x;x.r=cr;x.c=cc;x.cost = cur.cost+1;
firetime[cr][cc] = x.cost;
q1.push(x);
}
}
}
memset(vis, 0, sizeof(vis));
if(!bfs()) printf("IMPOSSIBLE\n");
}
return 0;
}