zoukankan      html  css  js  c++  java
  • BFS:HDU-1072-Nightmare

    Nightmare
    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 11404    Accepted Submission(s): 5579


    Problem Description

    Ignatius had a nightmare last night. He found himself in a labyrinth with a time bomb on him. The labyrinth has an exit, Ignatius should get out of the labyrinth before the bomb explodes. The initial exploding time of the bomb is set to 6 minutes. To prevent the bomb from exploding by shake, Ignatius had to move slowly, that is to move from one area to the nearest area(that is, if Ignatius stands on (x,y) now, he could only on (x+1,y), (x-1,y), (x,y+1), or (x,y-1) in the next minute) takes him 1 minute. Some area in the labyrinth contains a Bomb-Reset-Equipment. They could reset the exploding time to 6 minutes.

    Given the layout of the labyrinth and Ignatius' start position, please tell Ignatius whether he could get out of the labyrinth, if he could, output the minimum time that he has to use to find the exit of the labyrinth, else output -1.

    Here are some rules:
    1. We can assume the labyrinth is a 2 array.
    2. Each minute, Ignatius could only get to one of the nearest area, and he should not walk out of the border, of course he could not walk on a wall, too.
    3. If Ignatius get to the exit when the exploding time turns to 0, he can't get out of the labyrinth.
    4. If Ignatius get to the area which contains Bomb-Rest-Equipment when the exploding time turns to 0, he can't use the equipment to reset the bomb.
    5. A Bomb-Reset-Equipment can be used as many times as you wish, if it is needed, Ignatius can get to any areas in the labyrinth as many times as you wish.
    6. The time to reset the exploding time can be ignore, in other words, if Ignatius get to an area which contain Bomb-Rest-Equipment, and the exploding time is larger than 0, the exploding time would be reset to 6.
     

    Input

    The input contains several test cases. The first line of the input is a single integer T which is the number of test cases. T test cases follow.
    Each test case starts with two integers N and M(1<=N,Mm=8) which indicate the size of the labyrinth. Then N lines follow, each line contains M integers. The array indicates the layout of the labyrinth.
    There are five integers which indicate the different type of area in the labyrinth:
    0: The area is a wall, Ignatius should not walk on it.
    1: The area contains nothing, Ignatius can walk on it.
    2: Ignatius' start position, Ignatius starts his escape from this position.
    3: The exit of the labyrinth, Ignatius' target position.
    4: The area contains a Bomb-Reset-Equipment, Ignatius can delay the exploding time by walking to these areas.
     

    Output

    For each test case, if Ignatius can get out of the labyrinth, you should output the minimum time he needs, else you should just output -1.
     

    Sample Input

    3
    3 3
    2 1 1
    1 1 0
    1 1 3
    4 8
    2 1 1 0 1 1 1 0
    1 0 4 1 1 0 4 1
    1 0 0 0 0 0 0 1
    1 1 1 4 1 1 1 3
    5 8
    1 2 1 1 1 1 1 4
    1 0 0 0 1 0 0 1
    1 4 1 0 1 1 0 1
    1 0 0 0 0 3 0 1
    1 1 4 1 1 1 1 1
     

    Sample Output

    4
    -1
    13

    解题心得:
    1、还是可返回路劲,具体的可返回路径看点击打开链接。题不是很难,只要弄清楚初始化的顺序,充分理解好bfs就可以做出来了;
    2、这道题中需要求的使用的了最少时间和判断是否可返回的路径没有关系,bfs是按照顺序来的,使用的时间一定是逐步递增的,所以需要判断的是达到每一点还剩余的额的时间。
    3、注意初始化位置,不然很尴尬会产生来回走的死循环或者其他的一系列奇怪的问题。


    #include<bits/stdc++.h>
    using namespace std;
    int use[10][10],maps[10][10];
    int n,m;
    int dir[4][2] = {0,1,1,0,0,-1,-1,0};
    struct node
    {
        int x,y;
        int r_time;
        int use_time;
    }now,Next;
    
    bool check(int x,int y)
    {
        if(x<0 || y<0 || x>=n || y>=m || maps[x][y] == 0)
            return false;
        else
            return true;
    }
    
    void map_store()
    {
        memset(use,0,sizeof(use));//注意初始化的位置;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                scanf("%d",&maps[i][j]);
                if(maps[i][j] == 2)//找到起始点
                {
                    use[i][j] = 6;
                    now.x = i;
                    now.y = j;
                    now.r_time = 6;
                    now.use_time = 0;
                }
            }
        }
    }
    
    int bfs()
    {
        queue<node> qu;//每次调用bfs()时会定义一个新的队列;
        qu.push(now);
        while(!qu.empty())
        {
            now = qu.front();
            qu.pop();//不要忘记了;
            for(int i=0;i<4;i++)
            {
                Next.x = now.x + dir[i][0];
                Next.y = now.y + dir[i][1];
                Next.use_time = now.use_time + 1;
                Next.r_time = now.r_time - 1;
                if(Next.r_time == 0)
                {
                    break;
                }
                if(check(Next.x,Next.y))
                {
                    if(maps[Next.x][Next.y] == 3)
                        return Next.use_time;
                    else if(maps[Next.x][Next.y] == 4)
                        Next.r_time = 6;
                    if(Next.r_time > use[Next.x][Next.y])
                    {
                        qu.push(Next);
                        use[Next.x][Next.y] = Next.r_time;//use存储时间而不是简单的0-1标记;
                    }
                }
            }
        }
        return -1;//剩余时间用完但是什么都没有找到返回-1;
    }
    
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&m);
            map_store();
            int Use_time = bfs();
            printf("%d
    ",Use_time);
        }
    }
    


     
  • 相关阅读:
    中高级PHP程序员应该掌握哪些技术
    如何在FOXMAIL添加网易邮箱
    subline text 3快捷键
    【sublime】sublime Text 3 javaScript代码自动提示插件&安装步骤 &启动Debug模式
    PHPStorm常用快捷键
    怎么样快速修改HOSTS文件?让火绒等小工具来帮忙
    windows系统 右键新建菜单添加新建php文件
    给初学编程的人的干货
    安装Adobe Dreamweaver CC时出现安装失败及解决方法
    win10系统每次打开软件都会弹出账户控制如何解决
  • 原文地址:https://www.cnblogs.com/GoldenFingers/p/9107369.html
Copyright © 2011-2022 走看看