哈理工OJ 2034 Fire Maze【双BFS】【思维】
来源:互联网 发布:中国移动app软件下载 编辑:程序博客网 时间:2024/05/18 02:09
At first, Severus is located on the grid S. Every second he can only move to the four grids that adjacent to the grid he is
located on. The moment he move to any side of the maze, he will get rid of Figo.
After T seconds, Figo will reach the maze. Because Figo is the designer of the maze, when Figo arrive, he can reach any
grid if he want. If Severus can't leave the maze at that moment, there is no doubt that he will be caught by Figo.
Figo is very cunning. In the maze he set not only walls, but also fire! After every second, the fire will spread to the four
grid that adjacent to it. When a grid is on fire, certainly, Severus can not be on the grid. Can Severus escape from the
maze?
InputThe first line will be a integer CS, indicating the number of test cases.In every case, there will be three integer N, M, T.
After that there will be N * M characters, decribe the maze.
The "." is a empty grid, "#" is wall, "F" is the fire, "S" is the initial grid that Severus stands on.
10 <= n , m <= 100 10 <= T <=10000
OutputThere is only one line, if Severus can get out, output the mininum time he need to escape from the maze. If he can't,
output "Poor Severus must be caught by strong Figo!!!"
Sample Input24 4 4
####
#SF#
#..#
#..#
3 3 4
###
#S.
#.F
Poor Severus must be caught by strong Figo!!!
题目大意:S是起点,F是火,每一个回合火会烧到他四周的四个点,S也能走周围的四个点,问主人公是否能够逃离迷宫,(走到地图的四边就行,并且要在限制时间内)。
这里注意,火不一定只有一团,这里WA了好多发。。。
思路还是比较好确定的,双BFS,主要是要先想通先BFS谁,怎么BFS,这才是重点。这里我们先放放,首先要初始化,一会要对应思路和代码说话。
#include<stdio.h>#include<string.h>#include<iostream>#include<queue>using namespace std;//头文件struct zuobiao{ int x,y;}now,nex;//坐标结构体int step;//要输出的回合数。queue<zuobiao>s[2];//双BFS,就要双队列。char a[105][105];//地图。int vis[2][105][105];//是否走过这个点的判断(这里双BFS,就要用到两个图。)int dir[4][2]={ {1,0},{-1,0},{0,1},{0,-1} };int n,m,T;int ok;//这里如果是1表示走到了出口,并且没有被火烧到。如果是1表示还没走到出口。我们通过题干中的样例:
3 3 4
###
#S.
#.F
Poor Severus must be caught by strong Figo!!!能够判断出,如果S走到了出口,但是同时这个回合火烧到了出口,也是出不去的。所以我们这里确定了思路:每一个回合我都让火先烧,然后在用主人公走,烧过的地方当然是不能走的地方,如果这个时候主人公走到了没有火烧过的终点,那么他就是能够出去了。
这个时候我们对应一部分初步确定了思路的代码来详解:
void solve(int x,int y)//进来的xy是主人公的位子{ while (!s[0].empty()) s[0].pop();//我们每一次都要清空队列 while (!s[1].empty()) s[1].pop(); memset(vis,0,sizeof(vis));//清0 vis[0][x][y]=1; now.x=x; now.y=y; s[0].push(now);//我们这里规定0号队列是主人公队列。 for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { if(a[i][j]=='F')//因为不止一团火,所以我们遇到一个火就push进去一个火 { now.x=i; now.y=j; s[1].push(now); vis[1][i][j]=1; } } } while((!s[0].empty())||(!s[1].empty())) { step++;//一个回合加1;我们稍后探讨如何确定每个回合要怎么走。 bfs1();先让火去烧 bfs();//主人公再走 if(ok==1&&step<T)//如果主人公走完之后判断能够走到出口,并且在限制时间内完成了 { cout<<step+1<<endl;//输出回合数+1,(因为我是让火先烧的),这里好好理解一下就懂了 return ; } if(ok==1&&step>=T) { cout<<"Poor Severus must be caught by strong Figo!!!"<<endl;//如果走到了出口但是时间到了,还是相当于走不出去。 return ; } }}int main(){ int t; cin>>t; while(t--) { cin>>n>>m>>T; int sx,sy; for(int i=0;i<n;i++) { cin>>a[i]; for(int j=0;j<m;j++) { if(a[i][j]=='S') { sx=i; sy=j;//找到主人公的位子 } } } ok=0; step=0;//初始化回合数和ok solve(sx,sy);//进入函数 if(ok==0) { cout<<"Poor Severus must be caught by strong Figo!!!"<<endl; } }}
我们如何确定一个回合怎么走呢?我们知道,队列中的元素是不同回合push进去的,那么我们如何确定这个回合要走多少步呢?
int sum=s.size();就可以搞定啦~这个时候测定的sum就是这个回合一共能走的点的个数。
然后while(sum--)就行啦~
火烧部分:
void bfs1(){ int sum=s[1].size(); while(sum--) { now=s[1].front(); s[1].pop(); for(int i=0;i<4;i++) { nex.x=now.x+dir[i][0]; nex.y=now.y+dir[i][1]; if(nex.x>=0&&nex.x<n&&nex.y>=0&&nex.y<m&&vis[1][nex.x][nex.y]==0&&a[nex.x][nex.y]!='#')//火烧的就比较暴力无脑了,只要走到的地方不是墙,就尽情的让它烧吧。 { vis[1][nex.x][nex.y]=1; s[1].push(nex); } } }}最后是主人公的BFS:
void bfs(){ int sum=s[0].size(); while(sum--) { now=s[0].front(); s[0].pop(); for(int i=0;i<4;i++) { nex.x=now.x+dir[i][0]; nex.y=now.y+dir[i][1]; if(nex.x>=0&&nex.x<n&&nex.y>=0&&nex.y<m&&vis[0][nex.x][nex.y]==0&&a[nex.x][nex.y]!='#')//同样我们不能走到墙上 { if(vis[1][nex.x][nex.y]==1)//如果走到的这个地方虽然不是墙,但是让火烧过了,其实就表明这个点不用走了。因为走了也会被烧。 continue; s[0].push(nex);//如果没有火,就push进去。 vis[0][nex.x][nex.y]=1; if(nex.x==0||nex.y==0||nex.x==n-1||nex.y==m-1)//如果走到了终点 { ok=1;//ok==1;表示我走到了出口、 return ; } } } }}
最后上完整的AC代码:
#include<stdio.h>#include<string.h>#include<iostream>#include<queue>using namespace std;struct zuobiao{ int x,y;}now,nex;int step;queue<zuobiao>s[2];char a[105][105];int vis[2][105][105];int dir[4][2]={ {1,0},{-1,0},{0,1},{0,-1} };int n,m,T;int ok;void bfs1(){ int sum=s[1].size(); while(sum--) { now=s[1].front(); s[1].pop(); for(int i=0;i<4;i++) { nex.x=now.x+dir[i][0]; nex.y=now.y+dir[i][1]; if(nex.x>=0&&nex.x<n&&nex.y>=0&&nex.y<m&&vis[1][nex.x][nex.y]==0&&a[nex.x][nex.y]!='#') { vis[1][nex.x][nex.y]=1; s[1].push(nex); } } }}void bfs(){ int sum=s[0].size(); while(sum--) { now=s[0].front(); s[0].pop(); for(int i=0;i<4;i++) { nex.x=now.x+dir[i][0]; nex.y=now.y+dir[i][1]; if(nex.x>=0&&nex.x<n&&nex.y>=0&&nex.y<m&&vis[0][nex.x][nex.y]==0&&a[nex.x][nex.y]!='#') { if(vis[1][nex.x][nex.y]==1) continue; s[0].push(nex); vis[0][nex.x][nex.y]=1; if(nex.x==0||nex.y==0||nex.x==n-1||nex.y==m-1) { ok=1; return ; } } } }}void solve(int x,int y){ while (!s[0].empty()) s[0].pop(); while (!s[1].empty()) s[1].pop(); memset(vis,0,sizeof(vis)); vis[0][x][y]=1; now.x=x; now.y=y; s[0].push(now); for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { if(a[i][j]=='F') { now.x=i; now.y=j; s[1].push(now); vis[1][i][j]=1; } } } while((!s[0].empty())||(!s[1].empty())) { step++; bfs1(); bfs(); if(ok==1&&step<T) { cout<<step+1<<endl; return ; } if(ok==1&&step>=T) { cout<<"Poor Severus must be caught by strong Figo!!!"<<endl; return ; } }}int main(){ int t; cin>>t; while(t--) { cin>>n>>m>>T; int sx,sy; for(int i=0;i<n;i++) { cin>>a[i]; for(int j=0;j<m;j++) { if(a[i][j]=='S') { sx=i; sy=j; } } } ok=0; step=0; solve(sx,sy); if(ok==0) { cout<<"Poor Severus must be caught by strong Figo!!!"<<endl; } }}
- 哈理工OJ 2034 Fire Maze【双BFS】【思维】
- 哈理工 OJ Fire Maze(2次bfs)
- 哈理工OJ 2090 背包【思维】
- 哈理工OJ 2171 做菜【思维】
- 哈理工oj 2035 Diablo【BFS+DFS】
- 哈理工oj 2035Diablo 【bfs+dfs】
- hrbust/哈理工oj 1617 回家【BFS+BFS】
- 哈理工OJ 1652(思维题)1652 小球移动.
- 哈理工oj hrbust 2267 从前的运算符【思维】
- 哈理工 OJ 2215 Angle(简单的思维题)
- 哈理工oj 1739 sort problem【思维、水题】
- hrbust/哈理工oj 1634 super dog【思维】
- hrbust/哈理工oj 2220 强迫症【思维】
- hrbust/哈理工oj 1660素数矩阵【预处理+思维】
- 哈理工OJ 1453 AAAAHH! Overbooked!(水题,换思维)
- 哈理工OJ 1431 摞盘子 (思维水题)
- 哈理工OJ 1367 King【基础入门BFS】
- hrbust 哈理工OJ 1498Elevator Trouble【BFS过】
- 关于Android DES加密算法在不同平台加密结果不同的问题的一个解决方法
- 我的参考
- REST介绍
- IOS深浅拷贝的深入分析
- Android 快速入门 (D25)
- 哈理工OJ 2034 Fire Maze【双BFS】【思维】
- 《iOS Human Interface Guidelines》——Sound
- 逆向推演【微信消息列表】交互步骤细节+新手扫盲
- LoadRunner11压力测试时遇到问题及解决办法
- 对于301重定向情况下的模拟登录
- Brackets
- Xutils框架的使用
- Git命令(最常用10组)
- Zoho Books: 小企业如何应对债务