zoukankan      html  css  js  c++  java
  • hdu1242 Rescue(BFS +优先队列 or BFS )

    http://acm.hdu.edu.cn/showproblem.php?pid=1242
    题意:
        Angel被传说中神秘的邪恶的Moligpy人抓住了!他被关在一个迷宫中。迷宫的长、宽不超过200。 迷宫中有不可以越过的墙以及监狱的看守。 
    Angel的朋友带了一些救援队来到了迷宫中。他们的任务是:接近Angel。我们假设接近Angel就是到达Angel所在的位置。

    假设移动需要1单位时间,杀死一个看守也需要1单位时间。到达一个格子以后,如果该格子有看守,则一定要杀死。交给你的任务是,最少要多少单位时间,才能到达Angel所在的地方?(只能向上、下、左、右4个方向移动)

    Input

        该题含有多组测试数据。每组测试数据第一行二个整数n,m。表示迷宫的大小为n*m (N, M <= 200) 。 以后n行,每行m个时字符。其中“#”代表墙,“.”表示可以移动,“x”表示看守,“a”表示Angel,“r”表示救援队伍。字母均为小写。
    Output

        一行,代表救出Angel的最短时间。如果救援小组永远不能达到Angel处,则输出“Poor ANGEL has to stay in the prison all his life.”


    Sample Input

    7 8
    #.#####.
    #.a#..r.
    #..#x...
    ..#..#.#
    #...##..
    .#......
    ........
    

    Sample Output

    13

    分析:

        (N, M <= 200)  首先想到的是BFS, {P.S 有人dfs  0MS AC~~}

         可能有多个’r’,而’a’只有一个,从’a’开始搜,找到的第一个’r’即为所求。

          由于题目中增加了“x”表示看守这一个东东,经过“x”需要多耗一个单位时间。因此如果我们采用普通的宽搜,在第k层搜到了目标,但是耗时可能不止k个单位时间{有可能这条路径经过了“x”}。


        对此我有三个想法:

        1、采用优先队列(按到达该点的时候),这样就能保证最先扩展到目标状态的时候,耗时是最小的。

        2、把当扩展到“x”点时,把他放到与他耗时一样的那一层。这样也能保证到扩展到目标状态时,耗时是最小的。


    code1:(优先队列)

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <queue>
    using namespace std;
    
    int n, m;
    char map[205][205];
    int sx, sy;
    bool flag;
    struct node {
        int x, y, step;
        bool operator <(const node & t) const
        {
            return step>t.step;
        }
    };
    int dx[]= {-1,0,0,1};
    int dy[]= {0,-1,1,0};
    
    void bfs() {
        node now, tmp;
        int i,xx,yy;
        priority_queue<node> q;
        now.x = sx, now.y = sy, now.step = 0;
        map[sx][sy] = '#';
        q.push(now);
        while(!q.empty()) {
            now = q.top();
            q.pop();
    //         cout<<now.x<<" "<<now.y<<" "<<now.step<<endl;
            for(i=0; i<4; i++) {
                xx = now.x +dx[i];
                yy = now.y +dy[i];
                if(xx<0||xx>=n||yy<0||yy>=m||map[xx][yy]=='#') continue;
                if(map[xx][yy]=='r') {
                    cout<<now.step+1<<endl;
                    flag = true;
                    return ;
                }
                if(map[xx][yy]=='x') {
                    tmp.x =xx, tmp.y = yy, tmp.step = now.step+2;
                    q.push(tmp);
                } else {
                    tmp.x =xx, tmp.y = yy, tmp.step = now.step+1;
                    q.push(tmp);
                }
                map[xx][yy] = '#';
            }
        }
    }
    
    int main() {
        int i, j;
        while(~scanf("%d%d",&n,&m)) {
            for(i=0; i<n; i++)
                for(j=0; j<m; j++) {
                    cin>>map[i][j];
                    if(map[i][j]=='a')
                        sx=i,sy=j;
                }
            flag = false;
            bfs();
            if(!flag) printf("Poor ANGEL has to stay in the prison all his life.
    ");
        }
        return 0;
    }
    


    code2:(想法2)

    #include <iostream>
    #include <queue>
    #include <cstring>
    using namespace std;
    struct node
    {
        int x, y;
        int step;
    };
    queue<node> q;
    int N, M, prove, sx, sy, visit[202][202];
    char map[202][202];
    int dx[4] = {-1, 1, 0, 0};
    int dy[4] = {0, 0, 1, -1,};
    int check(int x, int y)
    {
        if(x < 0 || x >= N || y < 0 || y >= M)
            return 0;
        else
            return 1;
    }
    void BFS()
    {
        while(!q.empty())
            q.pop();
        node s, e;
        memset(visit, 0, sizeof(visit));
        s.step = 0;  s.x = sx;  s.y = sy;
        q.push(s);
        visit[s.x][s.y] = 1;
        while(!q.empty())
        {
            s = q.front();
            q.pop();
            if(map[s.x][s.y] == 'a')
            {
                cout << s.step << endl;
                prove =1;
            }
       //如取出的是在有警卫的格子中,即杀掉警卫再次进入队列
            if(map[s.x][s.y] == 'x') 
            {
                map[s.x][s.y] = '.';
                s.step += 1;
                q.push(s);
                continue;
            }
            for(int i = 0; i < 4; i++)
            {
                e.x = s.x + dx[i];  e.y = s.y + dy[i];
                if(!check(e.x, e.y) || visit[e.x][e.y] 
                || map[e.x][e.y] == '#')
                    continue;
        e.step = s.step + 1;
                q.push(e);
                visit[e.x][e.y] = 1;
    
       }
        }
    }
    int main()
    {
        while(cin >> N >> M)
        {
            for(int i = 0; i < N; i++)
            for(int j = 0; j < M; j++)
            {    
                cin >> map[i][j];
                if(map[i][j] == 'r')
                { sx = i;  sy = j; }
            }
            prove = 0;
            BFS();
            if(!prove)
                cout << "Poor ANGEL has to stay in the prison all his life." << endl;
        }
        return 0;
    }




  • 相关阅读:
    git线上操作
    IDEA快捷方式
    Java 四种线程池
    java 获取当前天之后或之前7天日期
    如何理解AWS 网络,如何创建一个多层安全网络架构
    申请 Let's Encrypt 通配符 HTTPS 证书
    GCE 部署 ELK 7.1可视化分析 nginx
    使用 bash 脚本把 AWS EC2 数据备份到 S3
    使用 bash 脚本把 GCE 的数据备份到 GCS
    nginx 配置 https 并强制跳转(lnmp一键安装包)
  • 原文地址:https://www.cnblogs.com/snake-hand/p/3206347.html
Copyright © 2011-2022 走看看