FZU 2196 Escape【BFS】

来源:互联网 发布:用友t3数据库安装 编辑:程序博客网 时间:2024/06/06 09:36

 Problem 2196 Escape

Accept: 173    Submit: 1030
Time Limit: 1000 mSec    Memory Limit : 32768 KB

 Problem Description

小明进入地下迷宫寻找宝藏,找到宝藏后却发生地震,迷宫各处产生岩浆,小明急忙向出口处逃跑。如果丢下宝藏,小明就能迅速离开迷宫,但小明并不想轻易放弃自己的辛苦所得。所以他急忙联系当程序员的朋友你(当然是用手机联系),并告诉你他所面临的情况,希望你能告诉他是否能成功带着宝藏逃脱。

 Input

有多组测试数据。

每组测试数据第一行是一个整数T,代表接下去的例子数。(0<=T<=10)

接下来是T组例子。

每组例子第一行是两个整数N和M。代表迷宫的大小有N行M列(0<=N,M<=1000)。

接下来是一个N*M的迷宫描述。

S代表小明的所在地。

E代表出口,出口只有一个。

.代表可以行走的地方。

!代表岩浆的产生地。(这样的地方会有多个,其个数小于等于10000)

#代表迷宫中的墙,其不仅能阻挡小明前进也能阻挡岩浆的蔓延。

小明携带者宝藏每秒只能向周围移动一格,小明不能碰触到岩浆(小明不能和岩浆处在同一格)。

岩浆每秒会向四周不是墙的地方蔓延一格。

小明先移动完成后,岩浆才会蔓延到对应的格子里。

小明能移动到出口,则小明顺利逃脱。

 Output

每组测试数据输出只有一行“Yes”或者“No”。 “Yes”代表小明可以成功逃脱。否则输出“No”。

 Sample Input

3
5 5
....!
S....
#....
!#...
#E...
2 2
S.
!E
2 2
SE
!.

 Sample Output

Yes
No
Yes

 Source

福州大学第十二届程序设计竞赛
思路来源:FZU 1408 位图【通过1找0的BFS、当然是多个1】、我们这里可以模仿这个题的做法,把所有!(岩浆源)看成1,然后遍历所有能走的点,标记上走到那里的时间。

解题思路:

分成两部分的BFS,第一部分用于处理!,标记上!到图上能够蔓延到的点的时间:

void bfsyu(){    while(!s.empty())//在输入图的时候入队所有!    {        now=s.front();        yanjiang[now.x][now.y]=now.output;//标记上时间        s.pop();        for(int i=0;i<4;i++)        {            nex.x=now.x+fx[i];            nex.y=now.y+fy[i];            if(nex.x>=0&&nex.x<n&&nex.y>=0&&nex.y<m&&vis[nex.x][nex.y]==0&&a[nex.x][nex.y]!='#')//在边界范围内,并且能够走到的地方            {                nex.output=now.output+1;                vis[nex.x][nex.y]=1;                s.push(nex);            }        }    }    return ;}
第二部分BFS,用于处理S到E

void bfs(int x,int y){    memset(vis,0,sizeof(vis));    while(!s.empty())    {        s.pop();    }    now.x=x;    now.y=y;    now.output=0;    s.push(now);//push进去起点    while(!s.empty())    {        now=s.front();        s.pop();        for(int i=0;i<4;i++)        {            nex.x=now.x+fx[i];            nex.y=now.y+fy[i];            if(nex.x>=0&&nex.x<n&&nex.y>=0&&nex.y<m&&a[nex.x][nex.y]!='#'&&a[nex.x][nex.y]!='!'&&vis[nex.x][nex.y]==0)//如果能走,并且没有走过            {                   if(a[nex.x][nex.y]=='E' && yanjiang[nex.x][nex.y]>=now.output+1)//如果走到的是终点并且人和岩浆同时到达终点,也算是可以逃脱,这里特判                {                    printf("Yes\n");                    return ;                }                if(yanjiang[nex.x][nex.y]!=-1)//正常走                {                    if(yanjiang[nex.x][nex.y]>now.output+1)//这块注意不能加等号了、在到达终点前,人和岩浆不可以一起到达一个地方。                    {                        nex.output=now.output+1;                        s.push(nex);                        vis[nex.x][nex.y]=1;                    }                }                else//如果是岩浆无法走到的点,但是人可以走的到,也要走下去                {                    nex.output=now.output+1;                    s.push(nex);                    vis[nex.x][nex.y]=1;                }            }        }    }    printf("No\n");    return ;}

完整AC代码:
#include<stdio.h>#include<string.h>#include<queue>using namespace std;int n,m;struct zuobiao{    int x,y,output;}now,nex;char a[1002][1002];int vis[1002][1002];int yanjiang[1002][1002];int fx[4]={0,0,1,-1};int fy[4]={-1,1,0,0};queue<zuobiao >s;void bfsyu(){    while(!s.empty())    {        now=s.front();        yanjiang[now.x][now.y]=now.output;        s.pop();        for(int i=0;i<4;i++)        {            nex.x=now.x+fx[i];            nex.y=now.y+fy[i];            if(nex.x>=0&&nex.x<n&&nex.y>=0&&nex.y<m&&vis[nex.x][nex.y]==0&&a[nex.x][nex.y]!='#')            {                nex.output=now.output+1;                vis[nex.x][nex.y]=1;                s.push(nex);            }        }    }    return ;}void bfs(int x,int y){    memset(vis,0,sizeof(vis));    while(!s.empty())    {        s.pop();    }    now.x=x;    now.y=y;    now.output=0;    s.push(now);    while(!s.empty())    {        now=s.front();             s.pop();        for(int i=0;i<4;i++)        {            nex.x=now.x+fx[i];            nex.y=now.y+fy[i];            if(nex.x>=0&&nex.x<n&&nex.y>=0&&nex.y<m&&a[nex.x][nex.y]!='#'&&a[nex.x][nex.y]!='!'&&vis[nex.x][nex.y]==0)            {                   if(a[nex.x][nex.y]=='E' && yanjiang[nex.x][nex.y]>=now.output+1)                {                    printf("Yes\n");                    return ;                }                if(yanjiang[nex.x][nex.y]!=-1)                {                    if(yanjiang[nex.x][nex.y]>now.output+1)                    {                        nex.output=now.output+1;                        s.push(nex);                        vis[nex.x][nex.y]=1;                    }                }                else                {                    nex.output=now.output+1;                    s.push(nex);                    vis[nex.x][nex.y]=1;                }            }        }    }    printf("No\n");    return ;}int main(){    int t;    while(~scanf("%d",&t))    {        while(t--)        {            while(!s.empty())            {                s.pop();            }            memset(yanjiang,-1,sizeof(yanjiang));            memset(vis,0,sizeof(vis));            int x,y;            scanf("%d%d",&n,&m);            for(int i=0;i<n;i++)            {                scanf("%s",a[i]);                for(int j=0;j<m;j++)                {                    if(a[i][j]=='S')                    {                        x=i;                        y=j;                    }                    if(a[i][j]=='!')                    {                        now.x=i;                        now.y=j;                        now.output=0;                        s.push(now);                        yanjiang[now.x][now.y]=0;                        vis[now.x][now.y]=1;                    }                }            }        bfsyu();        bfs(x,y);        }    }}/*36 6E.S..#####.#.....#.#####......######2 3S.E!..*/





0 0
原创粉丝点击