逃脱 (简单BFS)

题目传送门

G逃脱 

题目描述

这是mengxiang000和Tabris来到幼儿园的第四天,幼儿园老师在值班的时候突然发现幼儿园某处发生火灾,而且火势蔓延极快,老师在第一时间就发出了警报,位于幼儿园某处的mengxiang000和Tabris听到了火灾警报声的同时拔腿就跑,不知道两人是否能够逃脱险境?

幼儿园可以看成是一个N*M的图,在图中一共包含以下几种元素:

“.”:表示这是一块空地,是可以随意穿梭的。

“#”:表示这是一块墙,是不可以走到这上边来的,但是可以被火烧毁。

“S”:表示mengxiang000和Tabris所在位子。

“E”:表示幼儿园的出口。

“*”表示火灾发源地(保证输入只有一个火灾发源地)。

已知每秒有火的地方都会向周围八个格子(上下左右、左上、右上、左下、右下)蔓延火势.mengxiang000和Tabris每秒都可以选择周围四个格子(上下左右)进行移动。(假设两人这一秒行动完之后,火势才蔓延开)

根据已知条件,判断两人能否成功逃脱险境,如果可以,输出最短逃离时间,否则输出T_T。

为了防止孩子们嬉戏中受伤,墙体是橡胶制作的,可以燃烧的哦。

输入描述:

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

输出描述:

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

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

输出:

2
T_T
T_T

题意:就是两个人再S这个点,然后火灾*这里会向八个方向蔓延,求逃离最短时间,否则输出T_T;

题解:简单bfs,但是要注意WA点:如果到达了E,火再蔓延过来没事;如果到达了‘.’,火蔓延过来还是会死。

因为这个WA了好几发

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define MAX 35
#define INF 0x3f3f3f3f
int n,m;
int T;
char g[MAX][MAX];
bool vis[MAX][MAX];
int fire[MAX][MAX];
int ans=INF;
int dx[]={0,1,0,-1},dy[]={1,0,-1,0};
int sx,sy;
int fx,fy;
struct mask
{
    int x,y,step;
    mask(){}
    mask(int x,int y,int step):x(x),y(y),step(step){};
};
queue<mask>q;
bool check(int a,int b){return 0<=a&&a<n&&0<=b&&b<m;}
void fire_path()
{
    memset(vis,false,sizeof(vis));
    memset(fire,0,sizeof(fire));
    while(q.size()) q.pop();
    q.push(mask(fx,fy,0));
    vis[fx][fy]=true;
    fire[fx][fy]=0;
    while(q.size())
    {
        mask tmp=q.front();q.pop();
        for(int i=-1;i<=1;i++)
            for(int j=-1;j<=1;j++)
        {
            int nx=tmp.x+i;
            int ny=tmp.y+j;
            if(check(nx,ny)&&!vis[nx][ny])
            {
                vis[nx][ny]=true;
                fire[nx][ny]=tmp.step+1;
                q.push(mask(nx,ny,tmp.step+1));
            }
        }
    }
}
void bfs()
{
    memset(vis,false,sizeof(vis));
    while(q.size()) q.pop();
    vis[sx][sy]=true;
    q.push(mask(sx,sy,0));
    while(q.size())
    {
        mask tmp=q.front();q.pop();
        if(g[tmp.x][tmp.y]==‘E‘)
        {
            ans=min(ans,tmp.step);
            return ;
        }
        for(int i=0;i<4;i++)
        {
            int nx=dx[i]+tmp.x;
            int ny=dy[i]+tmp.y;          //注意这里要讨论一下
            if(g[nx][ny]==‘E‘&&tmp.step+1<=fire[nx][ny])
            {
                 vis[nx][ny]=true;
                q.push(mask(nx,ny,tmp.step+1));
            }
            if(check(nx,ny)&&!vis[nx][ny]&&g[nx][ny]!=‘#‘&&tmp.step+1<fire[nx][ny])
            {
                 vis[nx][ny]=true;
                q.push(mask(nx,ny,tmp.step+1));
            }
        }
    }
}
int main()
{
   cin>>T;
   while(T--){
        cin>>n>>m;
   for(int i=0;i<n;i++)
   {
       cin>>g[i];
       for(int j=0;j<m;j++)
       {
           if(g[i][j]==‘S‘)
           {
               sx=i;
               sy=j;
           }
           if(g[i][j]==‘*‘)
           {
               fx=i;
               fy=j;//cout<<i<<j<<endl;
           }
       }
     }
     ans=INF;
      fire_path();
      /*for(int i=0;i<n;i++)
      {
          for(int j=0;j<m;j++)
            cout<<fire[i][j];
          cout<<endl;
      }*/
      bfs();
      if(ans==INF)
        cout<<"T_T"<<endl;
      else cout<<ans<<endl;
   }
}


原文地址:https://www.cnblogs.com/zhgyki/p/9568761.html

时间: 2024-08-29 11:11:59

逃脱 (简单BFS)的相关文章

POJ 3278 Catch That Cow --- 简单BFS

/* POJ 3278 Catch That Cow --- 简单BFS */ #include <cstdio> #include <queue> #include <cstring> using namespace std; const int maxn = 100005; bool visit[maxn]; int step[maxn]; int bfs(int n, int k){ if (n == k) return 0; memset(visit, 0, s

【POJ 3669 Meteor Shower】简单BFS

流星雨撞击地球(平面直角坐标第一象限),问到达安全地带的最少时间. 对于每颗流星雨i,在ti时刻撞击(xi,yi)点,同时导致(xi,yi)和上下左右相邻的点在ti以后的时刻(包括t)不能再经过(被封锁).安全地带为永远不会被封锁的点. 简单bfs,开始WA在把平面空间上限当成300*300,但根据题目,这只是有流星雨撞击的范围.实际可走的空间理论上没上限,但分析可得,离原点最近的安全地带一定在(302,302)范围内,所以应可把数组至少开为303*303. 后来WA在把G[0][0]==1的情

LightOJ 1012 简单bfs,水

1.LightOJ 1012  Guilty Prince  简单bfs 2.总结:水 题意:迷宫,求有多少位置可去 #include<iostream> #include<cstring> #include<cmath> #include<queue> #include<algorithm> #include<cstdio> #define F(i,a,b) for (int i=a;i<=b;i++) using names

HDU 1548 A strange lift(Dijkstra,简单BFS)

题目大意: 电梯有两个选项向上或向下,每层楼有一个参数ki,代表电梯可以再该楼层的基础上向上或向下移动ki层,限制条件是向上不能超过楼层总数n,向下不能少于一.输入总层数n和当前所在层数以及目标层数,然后是n个数分别代表第i层的移动范围.输出最少移动次数,若不可达,输出-1. 解题思路: 1.用Dijkstra算法,首先构建邻接矩阵,注意在构造时,要考虑i-k[i]<1和i+k[i]>n,i代表当前所在层. 1 #include<string.h> 2 #include<st

poj 1562 简单 bfs

// 简单 bfs #include <iostream>#include<fstream>using namespace std; char map[110][110];int flag[110][110];int qu[11000][2],qe,qs,m,n;int add[8][2]={-1,-1,  -1,0, -1,1,   0,-1,  0,1,  1,-1,    1,0,   1,1 }; void bfs(int r,int c){    int i,tr,tc;

POJ3185(简单BFS,主要做测试使用)

没事做水了一道POJ的简单BFS的题目 这道题的数据范围是20,所以状态总数就是(1<<20) 第一次提交使用STL的queue,并且是在队首判断是否达到终点,达到终点就退出,超时:(其实这里我是很不明白的,,TM状态总数就只有1e6怎么也不应该超时的,,,,只能说STL的queue的常数实在是太大,完全没法弄...) 1 #include <map> 2 #include <set> 3 #include <stack> 4 #include <qu

POJ 1753 Flip Game 简单BFS

很简单的搜索题目,随便写. 题目链接 1 #include <stdio.h> 2 #include <string.h> 3 int st; 4 char s[10]; 5 int q[70000],vis[70000],front,tail; 6 const int dx[]={1,-1,0,0}; 7 const int dy[]={0,0,1,-1}; 8 int BFS() { 9 front=tail=0; 10 memset(vis,-1,sizeof(vis));

POJ - 2251 - Dungeon Master (简单BFS)

Dungeon Master Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 20450   Accepted: 7917 Description You are trapped in a 3D dungeon and need to find the quickest way out! The dungeon is composed of unit cubes which may or may not be filled

Dungeon Master (简单BFS)

Problem Description You are trapped in a 3D dungeon and need to find the quickest way out! The dungeon is composed of unit cubes which may or may not be filled with rock. It takes one minute to move one unit north, south, east, west, up or down. You