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;
    }




  • 相关阅读:
    Jfinal附件上传与重命名
    JFinal-BBS
    jFinal怎样连接sqlserver?
    关于jmeter响应结果用html查看乱码
    jmeter启动报错Error occurred during initialization of VM Could not reserve enough space for object heap errorlevel=1的解决方法
    Genymotion创建下载模拟器的时候出现Unable to create Genymotion virtual devices:Connection timeout错误
    Selenium IDE和Selenium RC的安装
    python+eclipse环境搭建
    第一个jemter测试脚本
    ulipad源码包配置环境及安装
  • 原文地址:https://www.cnblogs.com/snake-hand/p/3206347.html
Copyright © 2011-2022 走看看