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


 
原文地址:https://www.cnblogs.com/GoldenFingers/p/9107369.html