SLIKAR (BFS)

Problem Description

在一块 R×C 的矩形土地上,某天发起了洪水。洪水即将把整片土地淹没,于是 Beaver 不得不用最快的速度赶回老家,因为那里地势高,可以安全地避难。 在地图上,用“.”表示空地,用“D”表示老家的位置,用“S”表示Beaver 当前的位置,用“X”表示巨大的岩石,用“*”表示被洪水淹没的地区。每一个单位时间,Beaver 可以向上下左右四个方向移动一格,同样在已经有洪水的地区,洪水也能沿四个方向往外扩展一格。所有的岩石以及 Beaver 的老家都不会被水淹没,Beaver 也无法通过岩石阻碍的地方。任何一个时刻,都要保证Beaver不在洪水覆盖的区域。 
现在请写一个程序,告诉Beaver最快要多少时间可以安全到达老家。

Input

第一行给出两个正整数R和 C,均不超过50。 
接下来R行,每行包含C个字符,描述了整个地图。其中“D”和“S”有且仅有一个。

Output

输出所需要的最短时间,使 Beaver 可以安全到达老家。如果不存在这样的路,就输出“KAKTUS”。

Sample Input

3 3  
D.* 
... 
.S.

Sample Output

3
 
 
 
 
BFS,先预处理出,每个点被洪水淹没的时刻最小值,然后就直接bfs
 
 
#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
using namespace std;

struct node
{
    int x,y,t;
};
int dx[]={1,-1,0,0};
int dy[]={0,0,-1,1};
bool vis[55][55];
char s[55][55];
int r,c;
int tl[55][55];
int sx,sy,ex,ey;
//预处理
inline void bfs1(int x,int y)
{
    queue<node>q;
    node vn,vw;
    vn.x=x;
    vn.y=y;
    vn.t=0;
    vis[x][y]=1;
    q.push(vn);
    while(!q.empty())
    {
        vn=q.front(),q.pop();
        tl[vn.x][vn.y]=min(tl[vn.x][vn.y],vn.t);
        for(int i=0;i<4;i++)
        {
            int a=vn.x+dx[i];
            int b=vn.y+dy[i];
            if(a>=0&&a<r&&b>=0&&b<c&&s[a][b]!='D'&&s[a][b]!='X'&&!vis[a][b])
            {
                vis[a][b]=1;
                vw.x=a,vw.y=b,vw.t=vn.t+1;
                q.push(vw);
            }
        }
    }
}

inline void bfs2(int sx,int sy,int ex,int ey)
{
    node vn,vw;
    queue<node>q;
    vn.x=sx,vn.y=sy,vn.t=0;
    q.push(vn);
    while(!q.empty())
    {
        vn=q.front();q.pop();
        if(vn.x==ex&&vn.y==ey)
        {
            printf("%d\n",vn.t);
            return;
        }
        else
        {
            for(int i=0;i<4;i++)
            {
                int a=vn.x+dx[i];
                int b=vn.y+dy[i];
                int t=vn.t+1;
                if(a>=0&&a<r&&b>=0&&b<c&&!vis[a][b]&&s[a][b]!='X')
                {
                    if(t<=tl[a][b])
                    {
                        vis[a][b]=1;
                        vw.x=a,vw.y=b,vw.t=t;
                        q.push(vw);
                    }
                }
            }
        }
    }
    puts("KAKTUS");
}

int main()
{
    while(~scanf("%d%d",&r,&c))
    {
        for(int i=0;i<r;i++)
        {
            scanf("%s",s[i]);
        }
        for(int i=0;i<r;i++)
            for(int j=0;j<c;j++)
                tl[i][j]=100;
        //      printf("hh\n");
        for(int i=0;i<r;i++)
            for(int j=0;j<c;j++)
            {
                if(s[i][j]=='*')
                {
                    memset(vis,0,sizeof(vis));
                    vis[i][j]=1;
                    bfs1(i,j);
                }
                else if(s[i][j]=='S')
                {
                    sx=i,sy=j;
                }
                else if(s[i][j]=='D')
                {
                    ex=i,ey=j;
                }
            }
        //  printf("zz\n");
        memset(vis,0,sizeof(vis));
        vis[sx][sy]=1;
        bfs2(sx,sy,ex,ey);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值