zoukankan      html  css  js  c++  java
  • 【较复杂bfs】洪水-C++

    描述
    
    魔法森林的地图是R行C列的矩形。能通行的空地表示为'.',C君倾倒洪水的地点标记为'*',无法通行的巨石阵标记为'X',海狸的巢穴标记为'D',而画家和三只小刺猬的初始位置标记为'S'。
    
    每一分钟,画家和三个小刺猬可以走到相邻(上、下、左或右)的四个空地之一。与此同时,洪水每一分钟也会扩大到相邻(上、下、左或右)的所有的空地。一旦空地被淹没,就无法再通行。洪水无法通过巨石阵。但是海狸的巢穴建在很高的地方,永远不会淹没。
    
    注意,画家和三只小刺猬无法进入即将被淹没的空地,即如果他们与洪水在同一分钟到达某个空地,就不能进入。
    
    编写一个程序,给定一个魔法森林的地图,输出为了让画家和三只小刺猬安全地到达海狸的巢穴所需的最短时间。
    
    
    输入
    第1行:2个整数R,C
    
    接下来R行,每行C个字符 ('.', '*', 'X', 'D' 或 'S')
    
    地图只含有恰好1个'D'和1个'S',而'*'可能有零个或多个
    
    
    输出
    1个整数,表示最短的到达狸的巢穴所需的时间。如果无法到达,输出"KAKTUS"
    
    
    
    输入样例 1 
    
    3 6
    D...*.
    .X.X..
    ....S.
    输出样例 1
    
    6
    输入样例 2 
    
    3 3
    D.*
    ...
    ..S
    输出样例 2
    
    KAKTUS
    输入样例 3 
    
    3 3
    D.*
    ...
    .S.
    输出样例 3
    
    3
    提示
    
    数据规模:
    
    1<= N, M <= 1000
    

    思路:找到所有洪水打进队列,先深搜一次,新开一个二维数组a,表示洪水会在第a[i][j]秒到达位置(i,j),然后第二次搜索的时候的限制条件就只需要判断,目前时间加一是否小于等于下一步要走的点即可,这道题就难在需要两次搜索。

    代码如下

    //基于把所有信息糅合到一个标记数组...
    
    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 1010;
    int n, m;
    int a[maxn][maxn];
    int x_1, y_1, x_2, y_2;
    
    int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
    
    bool in(int x, int y)
    {
        return 1 <= x && x <= n && 1 <= y && y <= m;
    }
    queue<pair<int, int> > qu;
    void bfs1()
    {
        while(!qu.empty())
        {
            int x = qu.front().first;
            int y = qu.front().second;
            qu.pop();
            for(int i = 0; i < 4; i++)
            {
                int tx = x + dir[i][0];
                int ty = y + dir[i][1];
                if(in(tx, ty) && a[tx][ty] == 0)
                {
                    qu.push(make_pair(tx,ty));
                    a[tx][ty] = a[x][y] + 1;
                }
            }
        }
    }
    
    int bfs2()
    {
        queue<pair<int, int> > qu;
        qu.push(make_pair(x_1, y_1));
        a[x_1][y_1] = -1;
        while(!qu.empty())
        {
            int x = qu.front().first;
            int y = qu.front().second;
            qu.pop();
            for(int i = 0; i < 4; i++)
            {
                int tx = x + dir[i][0];
                int ty = y + dir[i][1];
                if(tx == x_2 && ty == y_2)
                    return abs(a[x][y]);
                if(in(tx, ty) &&(abs(a[x][y]-1) < a[tx][ty] || a[tx][ty]==0) )
                {
                    qu.push(make_pair(tx,ty));
                    a[tx][ty] = a[x][y]-1;
                }
            }
        }
        return -1;
    }
    
    int main()
    {
        cin >> n >> m;
        for(int i = 1; i <= n; i++)
        {
            for(int j = 1; j <= m; j++)
            {
                char ch;
                cin >> ch;
                if(ch == 'X') a[i][j] = -1;
                if(ch == 'S') x_1 = i, y_1 = j;
                if(ch == 'D') x_2 = i, y_2 = j, a[i][j]=-1;
                if(ch == '*'){qu.push(make_pair(i,j));a[i][j]=1;}
            }
        }
        
        bfs1();//void
        int ans = bfs2();
        if(ans == -1)
            cout << "KAKTUS" << endl;
        else 
        cout << ans << endl;//int
        
        return 0;
    }
    

    ov.

    个人博客地址: www.moyujiang.com 或 moyujiang.top
  • 相关阅读:
    linux下syscall函数 间接系统调用
    多线程 概述
    linux 信号与多线程
    linux ps命令介绍
    终端 进程关系
    shell 前台进程组的选择
    try catch finally的执行顺序到底是怎样的?
    OpenCV中遇到Microsoft C++ 异常 cv::Exception
    hdu1087Super Jumping! Jumping! Jumping!(最大递增序列和)
    [置顶] java Gui 键盘监听事件
  • 原文地址:https://www.cnblogs.com/moyujiang/p/11167789.html
Copyright © 2011-2022 走看看