BFS洪水

 试题描述:

已经连续下了几天雨,却还是没有停的样子。土豪CCY刚从外地赚完1e元回来,知道不久除了自己别墅,其他的地方都将会被洪水淹没。

CCY所在的城市可以用一个N*M(N,M<=50)的地图表示,地图上有五种符号:“. * X D S”。其中“X”表示石头,水和人都不能从上面经过。“.”表示平原,CCY和洪水都可以经过。“*”表示洪水开始地方(可能有多个地方开始发生洪水)。“D”表示CCY的别墅。“S”表示CCY现在的位置。

CCY每分钟可以向相邻位置移动,而洪水将会在CCY移动之后把相邻的没有的土地淹没(从已淹没的土地)。

求CCY回到别墅的最少时间。如果聪哥回不了家,就很可能会被淹死,那么他就要膜拜黄金大神涨RP来呼叫直升飞机,所以输出“ORZ hzwer!!!”。

输入:

第一行:N和M
接下来N行,每行M个字符,表示地图。

输出:

若能回家,输出一个整数,表示最少回家步数;否则输出“ORZ hzwer!!!”。

输入示例:

3 3
D.*
...
.S.

输出示例:

3

良心输入示例:

50 50
...SXX...XX...X...XX.XX....X.......X....X.X....*X.
.XX.X..XX.X.X..X.X.X...XX.X.....X....X...X.XX....X
..X..X....X.X.X.X.XX....XX...X..XX....X...XXX...XX
X.....X..XXX.XX..X.X.X........XXX....X.X..XX..X...
X..X.....X......X.......X..X......X.....X.X..X....
......XXX..X..XX.X.......X..X......X.X.XXX.X..X...
...X...XX.X..X.........X..XX..XX.X..X.X....X..X..X
XX.........XX.XXX.XXX...X..X..XXX.XX.X..X...X.X.X.
.....X...X..X.X.X.....X.X.X...XX........XX..X..X..
XXXX..XX..X..X..X..XXX..X...X..X.X...X..XX.XX.X...
......X..X....X.........XX..X..X........X.XX...X.X
X..XX...X........X........XXXX.XX.........X.X.XXX.
.....XXX...X.XXX....X...XX........X...XXXX...X....
.X.XX....XXX...X...X...X.X...XXX...X...X..XX.XX...
...XXX....XXX.....X.X...XX...X.X.XXX.X.XX..X......
.......X..XX.X.X..........X.XX..X..X.XX.XXXX...XX.
X...X.X.X.XXX.X..X.XXX..X...X....X.X..X...X..XX..X
..X..X.XX..X.XXX..X...X..X..X..X.X....X..........X
XX....X.X.X.XX.....X..XXXX.XX..X....X.....X.....X.
.XX.....X.X..X..X.X...X......X....X..X.XX.XX.XX.X.
.....X.........X..X.X...X....XX.X...X..X..XX.XX...
.X........X..XX..X...X....XX.XXX.XX.X..X...X...XXX
...X.X.XX...X......XX.X.XXX..X.X.XX....XXX.X...X..
....X.....XX..XX.X.X...X..X.X....X.....XX.XX..XXX.
....X........XXXXXX.........XX..X....XX.XXXX......
..XX.XXX.X...X.X.X.X..XXXX....X.X.X...XX.X..X..X..
XX..XX.X...X....XX....X.......X..X.X......XXXXX...
XX..XX.XX.X..X...XX....XX.X..X...X.X....X.........
..X.....X...X..X.........X......X...XX.XX...X.....
X.X..XX.X.X.X.XXXX.X...X..X...XX..X.....X.X.XXX...
..X....X.X.X......X..X...XX..X...X.X.XXX.X....XX.X
X.....X.X...XXXXX.....X..XX...X....X...XXX....X...
.XXX...XXXX.X....X...XX.XX..X.X........X...X....X.
..XXX.XX....X.XX.X..X...X.X.X.....X...X....X.XXXXX
.XX...X.X....XXX......X.....X....X.X..X..X....XX.X
XX..XX.X....X...XXX....X..XXX.XXX.X.X....X.X......
XX....X.X....X..X.XX...X..X.X....X..XX...XX...X...
X.X...X...X..X....X.X.........X...X...X....X..X...
.X...X...X.X....X.....XX......XXX..XX.XX.X.....X..
..X.X..XX.X..X..........X.X.XX..X..X.X.XXXX.......
..X...XX.X.X..XX..XXXXX...X........XX...X.X..X..XX
.....X..XXX....X.XX....XX.XX..XX.X....XX.XX..X.XXX
X..X.XX.X.X.......X.X.X..X......X..XX....X.XXX.XXX
X..XXXX.........X..X..X............X.X..X..X...X..
X...XX.XX...X........X....X....X.X...X..XD...X..X.
......X.......XXXX..XXX.....X.X.X.X..........X....
X.....XX.XX.XXX.XX.X.X..X.X.......XXXX.....X...XXX
.X..XX..X.....XX...XX..X.....XX...X..X....X..X..XX
X....XX....XX.....XX.X.XXX....X.......X..X....X..X
X.....XX..XX.X.....XX....X..X..X.X.XX.......X..X..

良心输出示例:

86

解题思路:

这是一道神奇的题目,我用了一天。。。。。

首先,我写了一个DFS+BFS,然后结果错误。

接着,改成预处理,创建一个step数组,step[i][j]表示洪水第几步漫道这里。

如:

3 3

D.*

...

.S.

的step是:

-1 1 0

3 2 1 

4 3 2

这需要一个BFS

读入·时每遇到一个*就把它丢到队列里面,

然后正常BFS。

预处理以后,就再正常地BFS

然后就好了。

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <queue>
using namespace std;
int map[51][51];
int step[51][51];
int book[51][51];
int startx, starty;
int endx,endy;
queue <int> Qx;
queue <int> Qy;
int n, m;
int ans = 0;
int wnum = 0;
void getstep()
{
    while(!Qx.empty())
    {
        int kx = Qx.front();
        int ky = Qy.front();
        Qx.pop();
        Qy.pop();
        if(map[kx-1][ky]==0 && step[kx-1][ky]>step[kx][ky]+1 && kx-1>0)
        {
            Qx.push(kx-1);
            Qy.push(ky);
            step[kx-1][ky]=step[kx][ky]+1;
        }
        if(map[kx+1][ky]==0 && step[kx+1][ky]>step[kx][ky]+1 && kx+1<=n)
        {
            Qx.push(kx+1);
            Qy.push(ky);
            step[kx+1][ky]=step[kx][ky]+1;
        }
        if(map[kx][ky-1]==0 && step[kx][ky-1]>step[kx][ky]+1 && ky-1>0)
        {
            Qx.push(kx);
            Qy.push(ky-1);
            step[kx][ky-1]=step[kx][ky]+1;
        }
        if(map[kx][ky+1]==0 && step[kx][ky+1]>step[kx][ky]+1 && ky+1<=m)
        {
            Qx.push(kx);
            Qy.push(ky+1);
            step[kx][ky+1]=step[kx][ky]+1;
        }
    }
}
int main()
{
    memset(book,88,sizeof(book));
    memset(step,88,sizeof(step));
    cin>>n>>m;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
        {
            char c;
            cin >> c;
            if (c == 'S')
            {
                startx = i;
                starty = j;
            }
            if (c == '*')
            {
                Qx.push(i);
                Qy.push(j);
                step[i][j]=0;
            }
            if (c == 'D')
            {
                endx=i;
                endy=j;
                map[i][j]=2;
            }
            if (c == 'X')
                map[i][j] = -1;
        }
    getstep();
    queue <int> qx;
    queue <int> qy;
    qx.push(startx);
    qy.push(starty);
    book[startx][starty]=0;
    while(!qx.empty())
    {
        int kx=qx.front();
        int ky=qy.front();
        qx.pop();
        qy.pop();
        if(map[kx][ky]==2)
            break;
        if((map[kx-1][ky]==0 || map[kx-1][ky]==2) && book[kx-1][ky]>book[kx][ky]+1 && step[kx-1][ky]>book[kx][ky]+1 && kx-1>=1)
        {
            qx.push(kx-1);
            qy.push(ky);
            book[kx-1][ky]=book[kx][ky]+1;
        }
        if((map[kx+1][ky]==0 || map[kx+1][ky]==2) && book[kx+1][ky]>book[kx][ky]+1 && step[kx+1][ky]>book[kx][ky]+1 && kx+1<=n)
        {
            qx.push(kx+1);
            qy.push(ky);
            book[kx+1][ky]=book[kx][ky]+1;
        }
        if((map[kx][ky+1]==0 || map[kx][ky+1]==2) && book[kx][ky+1]>book[kx][ky]+1 && step[kx][ky+1]>book[kx][ky]+1 && ky+1<=m)
        {
            qx.push(kx);
            qy.push(ky+1);
            book[kx][ky+1]=book[kx][ky]+1;
        }
        if((map[kx][ky-1]==0 || map[kx][ky-1]==2) && book[kx][ky-1]>book[kx][ky]+1 && step[kx][ky-1]>book[kx][ky]+1 && ky-1>=1)
        {
            qx.push(kx);
            qy.push(ky-1);
            book[kx][ky-1]=book[kx][ky]+1;
        }
    }
    if(book[endx][endy]>=1000000000)
        cout<<"ORZ hzwer!!!";
    else 
        cout<<book[endx][endy];
}

 

转载于:https://www.cnblogs.com/jason2003/p/7381373.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值