UVA 11624

来源:互联网 发布:庞博 程序员 编辑:程序博客网 时间:2024/06/08 00:48

题目大意:J在着火的迷宫中,他每次能移动一步,火每次四周蔓延,人和或都不能到障碍物处。问他能否逃脱,逃脱的步数。

解题思路:刚开始是只有一个人的bfs,火的蔓延根据人的步数,每次计算,结果就tle了。后面看了题解的思路,bfs人和火,如果一个位置火比人早到或同时到,则,这点直接continue。因为可能有很多把火所以与人走迷宫的区别在于,当这点没走过或是,走过的步数比将要走到的步数长就替换。先火bfs,在人bfs。

ac代码:

#include <iostream>#include <queue>#include <cstring>using namespace std;queue <int>qu;char a[1005][1005];int n, m, k, vis[1005][1005], temp, count;int x, y, fire[1005][1005], ex[1005][1005], f[1005][2];int dx[4] = {-1, 1, 0, 0}, dy[4] = {0, 0, -1, 1};void search(){count = 0;memset(vis, -1, sizeof(vis));memset(fire, -1, sizeof(fire));memset(ex, 0, sizeof(ex));for (int i=0; i<m; i++)for (int j=0; j<k; j++){if (a[i][j] == '#')vis[i][j] = 0;else if (a[i][j] == 'J')x = i, y = j;else if (a[i][j] == 'F'){f[count][0] = i;f[count++][1] = j;}if (i == 0 || j == 0 || i == m-1 || j == k-1)ex[i][j] = 1;}}int bfs1(){while (!qu.empty())qu.pop();qu.push(x);qu.push(y);vis[x][y] = 0while (!qu.empty()){int tt = qu.front();qu.pop();int kk = qu.front();qu.pop();if (fire[tt][kk] <= vis[tt][kk] && fire[tt][kk]!=-1)continue;if (ex[tt][kk])return vis[tt][kk];for (int i=0; i<4; i++){int xx = tt + dx[i];int yy = kk + dy[i];if (xx >= 0 && xx < m && yy >= 0 && yy < k && vis[xx][yy] == -1){qu.push(xx);qu.push(yy);vis[xx][yy] = vis[tt][kk] + 1;}} }return -1;}void bfs2(int X, int Y){while (!qu.empty())qu.pop();qu.push(X);qu.push(Y);fire[X][Y] = 0while (!qu.empty()){int tt = qu.front();qu.pop();int kk = qu.front();qu.pop();for (int i=0; i<4; i++){int xx = tt + dx[i];int yy = kk + dy[i];if (xx >= 0 && xx < m && yy >= 0 && yy < k && a[xx][yy] != '#' &&(fire[xx][yy] > fire[tt][kk]+1 ||fire[xx][yy] == -1)){qu.push(xx);qu.push(yy);fire[xx][yy] = fire[tt][kk] + 1;}} }}int main(){scanf("%d", &n);while (n--){scanf("%d%d", &m, &k);getchar();for (int i=0; i<m; i++)scanf("%s", a[i]);search();for (int i=0; i<count; i++)bfs2(f[i][0], f[i][1]);temp = bfs1();if (temp+1)printf("%d\n", temp+1);elseprintf("IMPOSSIBLE\n");}return 0;}
原创粉丝点击