UVA - 11624

题意:joe在一个迷宫里,迷宫的一些部分着火了,火势会向周围四个方向蔓延,joe可以向四个方向移动。火与人的速度都是1格/1秒,问j能否逃出迷宫,若能输出最小时间。

题解:先考虑模拟火,肯定是bfs(每次把同一时间着火的格子pop出来,再将它们周围的格子的t加一push进去)

    然后考虑怎么模拟人,现在人处在一个会变化的迷宫中。貌似很复杂。

    我们可以考虑t时刻的地图(假设我们bfs人的位置),着火的地方相当于墙壁,已经走过的地方也相当于墙壁(因为不可能回到已经走过的地方,这样要么出不去,要么走了回头路导致时间变长)。队列中存着当前时刻所有人可以到达的位置。考虑我们可以走的位置,除了边界与墙壁,如果我们知到一秒后哪些位置会着火,我们就不会走那些格子(否则就烧死了)。

于是便得到了一个算法,先让火烧一秒,然后人bjs一步,再烧1秒,再走一步。。。。

坑:一开始我先让人走一步,结果完全无法模拟人被火烧到的情况;

用queue的的时候老报错,总是pop空栈(因为没有考虑第一个与同一时刻的最后一个的特殊情况,结果写了一个很混乱的逻辑判断)

正确的方法是:

f v = F.front();
if (v.t == t) {...} else{return;}

#define  _CRT_SECURE_NO_WARNINGS
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<string.h>
#include<queue>
using namespace std;
typedef long long ll;
const int maxn = + ;
//模拟F,深搜J,
//F有多个,J一个
struct f {
int x, y, t;
f(int x = , int y = , int t = ) :x(x), y(y), t(t) {}
};
int dir[][] = { ,, ,-, ,, -, };
char map[maxn][maxn];
int vis[maxn][maxn], fired[maxn][maxn];
queue<f > F, J;
int R, C; int flag = ; int cnt = , square = ; int T = ;
bool check(int x, int y) {
if (map[x][y] == '#' || R < x || x <= || y <= || C < y)return ;
else return ;
}
void spread(int t) {//fire at (x,y) spread.//bfs1层 while (!F.empty()) {
f v = F.front();
if (v.t == t) {
map[v.x][v.y] = '#';
F.pop();
for (int i = ; i < ; i++) {
int dx = v.x + dir[i][], dy = v.y + dir[i][];
if (check(dx, dy))continue;
map[dx][dy] = '#';
F.push(f(dx, dy, v.t + ));
}
}
else return;
}
}
void bfs(int t) {//J runs at t
while (!J.empty()) {
f v = J.front();
if (v.t == t) {
J.pop();
for (int i = ; i < ; i++) {
int dx = v.x + dir[i][], dy = v.y + dir[i][];
if (dx <= || dx > R || dy <= || dy > C) { flag = v.t + ; while (!J.empty())J.pop(); return; }
if (map[dx][dy] != '#') {
map[dx][dy] = '#';
J.push(f(dx, dy, v.t + ));
}
}
}
else return;
}
}
int main() {
int t; cin >> t;
while (t--) {
while (!J.empty())J.pop();
while (!F.empty())F.pop();
cin >> R >> C;
for (int i = ; i <= R; i++) {
scanf("%s", map[i] + );
for (int j = ; j <= C; j++)if (map[i][j] == 'F') F.push(f(i, j, )), fired[i][j] = ; else if (map[i][j] == 'J')J.push(f(i, j, )), map[i][j] = '#';
}
flag = -;
T = ;
int tf = , tj = ;
while (!J.empty()) {
spread(T);
bfs(T);
T++;
if (flag > )break;
} if (flag == -)cout << "IMPOSSIBLE" << endl;
else cout << flag << endl;
}
cin >> t;
}

同学的想法是两次bfs,先bfs一次火的,把它抵达各个格子的时间填在一个表里,说明人在这个时间之后就不能走到这里了,把这个判断加到人的bfs里面即可

        #define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <vector>
#include <string.h> using namespace std;
char map[][];
int vis[][];
int tf[][];
int n, m, ji, jj, fi, fj;
struct Node {
int i, j;
Node(int i = , int j = ) :i(i), j(j) {}
};
queue<Node>q;
int dir[][] = { { , },{ -, },{ , },{ ,- } };
void bfsf() {
while (!q.empty()) {
Node t = q.front();
q.pop();
for (int k = ; k<; k++) {
int di = t.i + dir[k][];
int dj = t.j + dir[k][];
if (di< || di >= n || dj< || dj >= m || map[di][dj] == '#' || tf[di][dj] != -) continue;
q.push(Node(di, dj));
tf[di][dj] = tf[t.i][t.j] + ;
}
}
} int bfsj(int i, int j) {
queue<Node>que;
que.push(Node(i, j));
vis[i][j] = ;
while (!que.empty()) {
Node t = que.front();
que.pop();
if (t.i == || t.i == n - || t.j == || t.j == m - )
return vis[t.i][t.j] + ;
for (int k = ; k<; k++) {
int di = t.i + dir[k][];
int dj = t.j + dir[k][];
if (di< || di >= n || dj< || dj >= m || map[di][dj] == '#' || (vis[di][dj] != - || vis[t.i][t.j] + >= tf[di][dj]&&tf[di][dj]>)) continue;
que.push(Node(di, dj));
vis[di][dj] = vis[t.i][t.j] + ;
}
}
return -;
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
memset(tf, -, sizeof(tf));
scanf("%d%d", &n, &m);
for (int i = ; i<n; i++) {
scanf("%s", map[i]);
for (int j = ; j<m; j++) {
if (map[i][j] == 'J') ji = i, jj = j;
if (map[i][j] == 'F') q.push(Node(i, j)), tf[i][j] = ;
}
}
bfsf();
/*for (int i = 0; i < n; i++) {
for (int j = 0; j <= m; j++) cout << tf[i][j] << ' '; cout << endl;
}*/ memset(vis, -, sizeof(vis));
int ans = bfsj(ji, jj);
if (ans == -) printf("IMPOSSIBLE\n");
else printf("%d\n", ans); }
return ;
}

UVA - 11624 Fire! bfs 地图与人一步一步先后搜/搜一次打表好了再搜一次的更多相关文章

  1. UVA 11624 Fire! (bfs)

    算法指南白书 分别求一次人和火到达各个点的最短时间 #include<cstdio> #include<cstring> #include<queue> #incl ...

  2. UVA 11624 Fire! bfs 难度:0

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...

  3. UVA 11624 Fire! BFS搜索

    题意:就是问你能不能在火烧到你之前,走出一个矩形区域,如果有,求出最短的时间 分析:两遍BFS,然后比较边界 #include<cstdio> #include<algorithm& ...

  4. BFS(两点搜索) UVA 11624 Fire!

    题目传送门 /* BFS:首先对火搜索,求出火蔓延到某点的时间,再对J搜索,如果走到的地方火已经烧到了就不入队,直到走出边界. */ /******************************** ...

  5. UVa 11624 Fire!(着火了!)

    UVa 11624 - Fire!(着火了!) Time limit: 1.000 seconds Description - 题目描述 Joe works in a maze. Unfortunat ...

  6. E - Fire! UVA - 11624(bfs + 记录火到达某个位置所需要的最小时间)

    E - Fire! UVA - 11624 题目描述 乔在迷宫中工作.不幸的是,迷宫的一部分着火了,迷宫的主人没有制定火灾的逃跑计划.请帮助乔逃离迷宫.根据乔在迷宫中的位置以及迷宫的哪个方块着火,你必 ...

  7. UVA 11624 Fire!【两点BFS】

    Joe works in a maze. Unfortunately, portions of the maze have caught on fire, and the owner of the m ...

  8. UVa 11624 Fire!(BFS)

    Fire! Time Limit: 5000MS   Memory Limit: 262144KB   64bit IO Format: %lld & %llu Description Joe ...

  9. (简单) UVA 11624 Fire! ,BFS。

    Description Joe works in a maze. Unfortunately, portions of the maze have caught on fire, and the ow ...

随机推荐

  1. Git------解决右键不显示Git Bash Here问题

    步骤: 1.通过在“运行”中输入‘regedit’,打开注册表. 2.找到[HKEY_CLASSES_ROOT\Directory\Background]. 3.在[shell]下右键-新建项[ope ...

  2. Java 流(Stream)、文件(File)和IO -- Java ByteArrayInputStream类

    字节数组输入流在内存中创建一个字节数组缓冲区,从输入流读取的数据保存在该字节数组缓冲区中.创建字节数组输入流对象有以下几种方式. 接收字节数组作为参数创建: ByteArrayInputStream ...

  3. ios开发之--UIViewContentMode详解

    在开发当中有时会有这样的需求,将从服务器端下载下来的图片添加到imageView 当中展示,但是下载下来的图片尺寸大小不固定,宽高也有可能不成比例 如果直接设置imageView的image属性而不设 ...

  4. iOS in-app purchase详解

    in-app purchase教程: http://www.appcoda.com/in-app-purchase-tutorial/ 3.后台服务器验证收据的正确性 IOS 内支付有两种模式: 1) ...

  5. 【代码审计】XIAOCMS_存在任意文件删除漏洞分析

      0x00 环境准备 XIAOCMS官网: http://www.xiaocms.com/ 网站源码版本:XiaoCms (发布时间:2014-12-29) 程序源码下载:http://www.xi ...

  6. 【安全开发】python安全编码规范

    申明:本文非笔者原创,原文转载自:https://github.com/SecurityPaper/SecurityPaper-web/blob/master/_posts/2.SDL%E8%A7%8 ...

  7. Python爬虫学习笔记-1.Urllib库

    urllib 是python内置的基本库,提供了一系列用于操作URL的功能,我们可以通过它来做一个简单的爬虫. 0X01 基本使用 简单的爬取一个页面: import urllib2 request ...

  8. CMake INSTALL 命令设置exe dll lib的安装位置

    install(TARGETS ${OUT_NAME} RUNTIME DESTINATION ${CMAKE_BINARY_DIR}/bin LIBRARY DESTINATION ${CMAKE_ ...

  9. pojo与DTO的区别

    ational Mapping(对象关系映射)的缩写.通俗点讲,就是将对象与关系数据库绑定,用对象来表示关系数据.在O/R Mapping的世界里,有两个基本的也是重要的东东需要了解,即VO,PO. ...

  10. SimpleDateFormat 取当前周的周一和周日的日期,当前月第一个和最后一天的日期

    /** * 类说明 :以及获取当前周的周一和周日的日期,当前月第一个和最后一天的日期 * 日期格式化:格式参数  G 年代标志符  y 年 M 月 d 日    h 时 在上午或下午 (1~12)  ...