题目:

这是mengxiang000和Tabris来到幼儿园的第四天,幼儿园老师在值班的时候突然发现幼儿园某处发生火灾,而且火势蔓延极快,老师在第一时间就发出了警报,位于幼儿园某处的mengxiang000和Tabris听到了火灾警报声的同时拔腿就跑,不知道两人是否能够逃脱险境? 幼儿园可以看成是一个N*M的图,在图中一共包含以下几种元素: “.”:表示这是一块空地,是可以随意穿梭的。 “#”:表示这是一块墙,是不可以走到这上边来的,但是可以被火烧毁。 “S”:表示mengxiang000和Tabris所在位子。 “E”:表示幼儿园的出口。 “*”表示火灾发源地(保证输入只有一个火灾发源地)。 已知每秒有火的地方都会向周围八个格子(上下左右、左上、右上、左下、右下)蔓延火势.mengxiang000和Tabris每秒都可以选择周围四个格子(上下左右)进行移动。(假设两人这一秒行动完之后,火势才蔓延开) 根据已知条件,判断两人能否成功逃脱险境,如果可以,输出最短逃离时间,否则输出T_T。

输入描述:

第一行输入一个整数t,表示一共的测试数据组数。 第二行输入两个整数n,m,表示幼儿园的大小。 接下来n行,每行m个字符,表示此格子是什么元素。 t<=200 3<=n<=30 3<=M<=30 保证图中有一个起点,一个出口,一个火灾源处.

输出描述:

每组数据输出一行,如果两人能够成功到达出口,那么输出最短逃离时间,否则输出T_T
示例1

输入

3
5 5
*....
.....
..S#.
...E.
.....
5 5
...#*
..#S#
...##
....E
.....
5 5
.....
S....
..*#.
...E.
.....

输出

2
T_T
T_T

解析:  这题乍一看挺简单(确实挺简单),但本人尝试多次竟然没有AC,异常难受~ o(TωT)o   一开始的思路(有误,写给自己的,可以略过):存图,然后将小盆友和火同时Bfs,嗯就是这里出问题了,火焰和人的拓展条件并不一样,所以,在入队的数量并不同,SO拓展并不是同步的!!_φ(❐_❐✧ 人丑就要多WA  接着在网上找了个正解(https://www.cnblogs.com/zhgyki/p/9568761.html),模仿着自己写了一个,理一下其思路:将火焰的拓展和人的拓展分隔开,先将火焰拓展,利用时间作为之后的比较中介,将火焰到达每个点的时间记录在该点(这个思路如此牛*)。接着是人的Bfs,注意遇到出口时,时间小于或等于该点火焰蔓延到的时间即可(题目说明了火焰蔓延是后滞的),然后普通的逃脱到的点的时间要严格小于火焰到达的时间。  正解:

  1 #include <iostream>
  2 #include <cstring>
  3 #include <queue>
  4 using namespace std;
  5 typedef long long ll;
  6 #define maxn 35
  7 #define Inf 0x7fffffff
  8 int n=0,m=0,ans=Inf;
  9 int t=0;
 10 char Map[maxn][maxn];
 11 bool vis[maxn][maxn]={0};
 12 int fir[maxn][maxn]={0};//记录fire到每一格所需时间
 13 int dir[][2]={
 14     {1,0},{-1,0},{0,1},{0,-1},
 15     {1,1},{-1,-1},{-1,1},{1,-1}
 16 };
 17 struct Point{
 18     int x,y,tm;
 19     Point(){tm=0;}
 20     Point(int a,int b,int c):x(a),y(b),tm(c){}
 21 }fi,st;
 22 void FireGo()
 23 {
 24     memset(vis,false,sizeof(vis));
 25     memset(fir,0,sizeof(fir));
 26     queue<Point> q;
 27     q.push(fi);
 28     vis[fi.x][fi.y]=true;
 29     while(q.size())
 30     {
 31         Point head=q.front();
 32         q.pop();
 33         for(int i=0;i<8;++i)
 34         {
 35             int nx=head.x+dir[i][0];
 36             int ny=head.y+dir[i][1];
 37             if(nx<0||nx>=n||ny<0||ny>=m) continue;
 38             if(vis[nx][ny]) continue;
 39             vis[nx][ny]=true;
 40             fir[nx][ny]=head.tm+1;//计算每个点有火势蔓延到的时间
 41             q.push({nx,ny,head.tm+1});
 42         }
 43     }
 44 }
 45 bool Bfs()
 46 {
 47     memset(vis,0,sizeof(vis));//重新初始vis数组
 48     queue<Point> q;
 49     q.push(st);
 50     vis[st.x][st.y]=true;
 51     while(q.size())
 52     {
 53         Point head=q.front();
 54         q.pop();
 55         for(int i=0;i<4;++i)
 56         {
 57             int nx=head.x+dir[i][0];
 58             int ny=head.y+dir[i][1];
 59             if(nx<0||nx>=n||ny<0||ny>=m) continue; //越界
 60             if(vis[nx][ny]) continue;
 61             if(Map[nx][ny]=='#') continue;
 62             if(Map[nx][ny]=='E' &&head.tm+1<=fir[nx][ny])//先到出口,火才到
 63             {
 64                 //vis[nx][ny]=true;
 65                 //q.push({nx,ny,head.tm+1}); continue;
 66                  ans=head.tm+1;
 67                 return true;
 68             }
 69             if(head.tm+1<fir[nx][ny]){//要严格小于,==时本秒结束火就到
 70                 vis[nx][ny]=true;
 71                 q.push({nx,ny,head.tm+1});
 72             }
 73
 74         }
 75     }
 76     return false;
 77 }
 78 int main()
 79 {
 80     cin>>t;
 81     while(t--)
 82     {
 83         cin>>n>>m;
 84         for(int i=0;i<n;++i)
 85         for(int j=0;j<m;++j)
 86         {
 87             cin>>Map[i][j];
 88             if(Map[i][j]=='S'){
 89                 st.x=i; st.y=j;
 90             }
 91             else if(Map[i][j]=='*'){
 92                 fi.x=i; fi.y=j;
 93             }
 94         }
 95         FireGo();
 96         if(Bfs()) cout<<ans<<endl;
 97         else cout<<"T_T"<<endl;
 98     }
 99     return 0;
100 }

View Code

  错解:

 1 #include <iostream>           //不能将火 和人同时bfs()两者的拓展条件不同,入队的数量不同,导致拓展不同步
 2 #include <queue>
 3 #include <cstring>
 4 using namespace std;
 5 int n=0,m=0;
 6 char Map[30][30]={0};
 7 bool vis[30][30]={0};
 8 bool judge[30][30]={0};
 9 struct Point{
10     int x,y,tm;
11     Point(){ x=0; y=0; tm=0; }
12     Point(int a,int b,int c){ x=a; y=b; tm=c; }
13 }fi,en,st;
14 int dir[][2]={
15     {0,1},{1,0},{0,-1},{-1,0},
16     {1,1},{-1,-1},{1,-1},{-1,1} //斜方向
17 };
18 bool Check(int x,int y)//该点8方都不能有火源才安全
19 {
20     for(int i=0;i<8;++i)
21     {
22         if(Map[x+dir[i][0]][y+dir[i][1]]=='*')
23             return false;
24     }
25     return true;
26 }
27 int bfs()//fire 和 人同时移动
28 {
29     memset(vis,false,sizeof(vis));
30     memset(judge,false,sizeof(judge));
31     queue<Point> q;
32     st.tm=0;
33     q.push(st);
34     vis[st.x][st.y]=true;
35     while(!q.empty())
36     {
37         Point head=q.front();
38         q.pop();
39         for(int i=0;i<4;++i) //四方向遍历
40         {
41             int nx=head.x+dir[i][0];
42             int ny=head.y+dir[i][1];
43             if(nx<0||nx>=n||ny<0||ny>=m) continue; //越界
44             if(Map[nx][ny]=='E') return (head.tm+1); //到达出口
45             if(vis[nx][ny]) continue;
46             if(Map[nx][ny]=='#'||Map[nx][ny]=='*')  continue; //墙 火
47             if(!Check(nx,ny)) continue; //到达的点不安全
48             vis[nx][ny]=true;
49             q.push({nx,ny,head.tm+1});
50         }
51         if(q.empty()) return 0;
52         //火势蔓延
53         for(int i=0;i<8;++i)//这里出错,火的蔓延也应要用到队列不然其实并未伸展
54         {
55             int nx=fi.x+dir[i][0];
56             int ny=fi.y+dir[i][1];
57             judge[nx][ny]=true;
58             if(nx<0||nx>=n||ny<0||ny>=m) continue; //越界
59             if(judge[nx][ny]) continue;
60             if(Map[nx][ny]=='E') return 0; //出口被烧
61             Map[nx][ny]='*';
62         }
63     }
64     return 0;
65 }
66 int main()
67 {
68     int t=0;
69     cin>> t;
70     while(t--)
71     {
72         cin>> n>> m;
73         for(int i=0;i<n;++i)
74         for(int j=0;j<m;++j)
75         {
76             cin>> Map[i][j];
77             if(Map[i][j]=='E'){
78                 en.x=i; en.y=j;
79             }
80             else if(Map[i][j]=='*'){
81                 fi.x=i; fi.y=j;
82             }
83             else if(Map[i][j]=='S'){
84                 st.x=i; st.y=j;
85             }
86         }
87         int temp=bfs();
88         if(temp) cout<<temp<<endl;
89         else cout<<"T_T"<<endl;
90     }
91     return 0;
92 }

View Code

转载于:https://www.cnblogs.com/GorgeousBankarian/p/10380705.html

Bfs 逃脱(牛客网)相关推荐

  1. 牛客网挑战赛24 青蛙(BFS)

    链接:https://www.nowcoder.com/acm/contest/157/E 来源:牛客网 有一只可爱的老青蛙,在路的另一端发现了一个黑的东西,想过去一探究竟.于是便开始踏上了旅途 一直 ...

  2. 牛客网 - 小乐乐打游戏(BFS)

    链接:https://ac.nowcoder.com/acm/contest/301/G 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言65536 ...

  3. 牛客网平台常州大学新生寒假训练会试

    A-添加逗号 链接:https://www.nowcoder.net/acm/contest/78/A 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其 ...

  4. 牛客网【每日一题】7月8日 Alliances

    来源:牛客网 文章目录 题目描述 题解: 代码: 时间限制:C/C++ 5秒,其他语言10秒 空间限制:C/C++ 262144K,其他语言524288K 64bit IO Format: %lld ...

  5. 【转自牛客网】C++类职位校招

    作者:./a.out 链接:https://www.nowcoder.com/discuss/14022 来源:牛客网 话说在牛客网上混迹了半年,也没啥拿的出手的贡献.现在基本上自己的校招生涯要告一段 ...

  6. 今日头条后端面经总结(2018.12月)(转自牛客网)

    面经(后端): 一 操作系统中的进程和线程还有虚拟存储. 计算机网络TCP和UDP仔细看一下,也不要放过滑动窗口; 还有计算机网络体系结构各层都要熟悉. lambda表达式 spring 智力题,比如 ...

  7. 【2020牛客网笔试整理】小红书笔试题

    薯队长写了一篇笔记草稿,请你帮忙输出最后内容. 1.输入字符包括,"(" , ")" 和 "<"和其他字符. 2.其他字符表示笔记内容 ...

  8. 牛客网 2018校招真题 美团点评 重要节点

    Description 牛客网 2018校招真题 重要节点 Solving Ideas BFS 创建一个标记数组arrive,arrive[i][j]为true表示从i可以到达j, false则不能 ...

  9. 算法记录 牛客网 leetcode刷题记录

    算法记录 & 牛客网 & leetcode刷题记录 解题思路 STL容器 常用算法模板 堆排序 插入排序 快速排序 BFS层序遍历 二叉树 JZ55 二叉树的深度 BST(binary ...

  10. [C++] 牛客网:合并两个有序的数组

    主要是体验一下牛客网里的核心代码模式到底是怎么弄的..还有C++这个东西平常用的太少了,试一试. 以外的还体验到了sort()函数的使用. 来源:牛客网 题目链接:合并两个有序的数组 知识点:数组.双 ...

最新文章

  1. linux的子进程和父进程,[Linux进程]在父进程和子进程中分别对文件进行操作
  2. python 递归乘法
  3. 简单讲解一下负载均衡、反向代理模式的优点、缺点
  4. 关闭Vue计算属性自带的缓存功能
  5. matlab计算曲线形心,并将y轴移动到形心上,使图形居中布置
  6. 文件操作(上传,下载,限制)
  7. idea2020.1使用Lombok注解,点击运行项目提示找不到get,set方法?
  8. 10 SystemVerilog语言编写SPI发送
  9. android volley设置编码,Volley 概览  |  Android 开发者  |  Android Developers
  10. html当当网上书店,当当网上书店案例代码+css+js+images
  11. Python压缩解压–zipfile
  12. ansys与solidworks关联失败,将SolidWorks模型导入ansys划分网格总是提示错误
  13. Windows10使用diskpart分区
  14. pc机 串口 并口 com口 详解
  15. 11_05.【Java】线程安全与线程同步
  16. 软件测试方法口诀,自测记忆法
  17. Vue - 加载静态图片的方式
  18. pandorabox安装迅雷远程下载插件
  19. c语言字符串dna,转录流程(c语言编写DNA转录程序)
  20. spring事务的传播行为的讲解(笔记 侵删)

热门文章

  1. 实现财务自由-《富爸爸穷爸爸》读书语句摘抄
  2. 减小服务器负担,Apache启用mod_expires模块
  3. 【bzoj2118】 墨墨的等式
  4. 30个免费网页设计模板
  5. js中的null VS undefined
  6. returned message 找不到可安装的 ISAM。.
  7. mysql(安装、启动、删除)服务
  8. (转)Mysql 增删用户
  9. iOS-Senior19-FMDB第三方应用
  10. c++模板函数实例化的偏序机制