hdu1072 Nightmare(BFS)

            已经好久没刷题了,之前因为期末考的原因(其实很大程度是是因为看小说委屈)。现在期末考结束了,也放假了(小说也看完了)。今天在家闲得蛋疼,就把上一次没做完的搜索题做下。这一题之前的时候思路有但是一个关键部分的代码实现没想到。今天做的时候参考了一下别人的代码突然之间有一种醍醐灌顶的感觉大笑

   现在我说一下这一题的思路吧:

   这一题与之前的搜索题有一定的区别,最大的区别就是这一题的迷宫可以走“回头路”。我认为这也是本题的最大难点,换句话就是你解决了这个问题也就相当于完成了90%。所以这一题不能像之前搜索一样的去标记走过的路,因为可能还要再走一趟。这样就引发了一个问题,如果不做处理的话,那么就永远走不出来了。所以不是不做处理而是做特殊的处理:利用前后两次踏上同一位置距离炸弹爆炸的时间来判断,如果第二次剩的时间更的话,那么就入队;反之,入队就没有什么意义了。

   从以上分析来看4的所在的位置无论怎么走,都只走一次,所以可以访问过的4标记为0.这样下一次就不会访问到了。所以也可以用这个作为另一种解法。

   当然如果将以上两种方式结合起来的话,那么可以提高搜索的效率。

(题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1072)

具体的参考代码:

#include <iostream>
#include <queue>
#include <string.h>
using namespace std;
typedef struct{
    int x,y,step,time;          //step表示所走步数,time表示离爆炸的时间
}coordinate;
int n,m;                               //表示迷宫的规格
int labyrinth[10][10],mark[10][10];   //labyrinth表示地图,mark标记访问的点
const int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0}; //位移参量
coordinate start;
queue<coordinate>Q;
void Init(){
    memset(labyrinth,0,sizeof(labyrinth));
    memset(mark,0,sizeof(mark));
}
bool Inborder(int x,int y){        //判断是否出界
    if(x<0||x>=n||y<0||y>=m)
        return false;
    return true;
}
void BFS(){
    coordinate now,next;
    while(!Q.empty())     //队列初始化
        Q.pop();
    Q.push(start);
    mark[start.x][start.y] = 6;   //将起始点的时间记为6
    while( !Q.empty() ){
        now=Q.front();
        Q.pop();
        for(int i=0 ; i<4 ; i++ ){
            next.x = now.x + dx[i];       //进行四个方向的遍历
            next.y = now.y + dy[i];
            if( labyrinth[next.x][next.y]!=0 && Inborder(next.x,next.y) ){
                //该点不是0且不出界则访问该点
                next.step = now.step + 1;
                next.time = now.time - 1;
                if( labyrinth[next.x][next.y] == 4 ){
                    labyrinth[next.x][next.y] = 0;
                    next.time = 6;
                }
                else if( labyrinth[next.x][next.y] == 3 ){
                    if(next.time>0)
                        cout<<next.step<<endl;
                    else
                        cout<<-1<<endl;
                    return ;
                }
                if( next.time>1 && mark[next.x][next.y]<next.time ){
                    //满足条件则入列
                    mark[next.x][next.y] = next.time;
                    Q.push(next);
                }
            }
        }
    }
    cout<<-1<<endl;
    return ;
}
int main()
{
    int T;
    cin>>T;
    while(T--){
        cin>>n>>m;
        Init();
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                cin>>labyrinth[i][j];
                if(labyrinth[i][j]==2){
                //查找起点位置
                    start.x=i;
                    start.y=j;
                    start.step=0;
                    start.time=6;
                }
            }
        }
        BFS();
    }
    return 0;
}


 

你可能感兴趣的:(hdu1072 Nightmare(BFS))