木乃伊迷宫

1147.木乃伊迷宫

时限:1000ms 内存限制:10000K 总时限:3000ms

描述

木乃伊地下宫殿是一个6行6列的迷宫。游戏在木乃伊所在的迷宫里展开,任务就是尽快赶到出口。你一次只能走一步,而木乃伊可以走两步,但木乃伊是很笨的,他总是先尽量跟你达到同一列,如果已经是同一列了,他才会向你走来,有墙的地方人和木乃伊都不能过,你可以利用障碍物牵制住木乃伊。

输入

先输入墙的数量n,然后在后续的n行里每行有3个数表示一堵墙,3个数分别为格子的行、列和墙的位置(0表示这个格子的下方是墙,1表示这个格子的右方是墙),再下来的3行每行2个数,分别表示木乃伊、人还有出口的位置。

输出

如果能安全逃生则输出Yes,否则输出No,答案占一行。

代码:

#include<iostream>
#include<queue>
using namespace std;


int maze[6][6][2];//用来存储迷宫信息。
int n;//墙的数量
typedef struct node{//定义节点结构体
int px,py;
int mx,my;
int useful;//判断这个节点是否有效

};
node start,target;//定义起始点和终点
queue<node>q;//用作bfs的队列
int visited[6][6][6][6];//避免重复访问
int direction[4][2]={//往哪个方向走,相应的x,y都要变化
0,-1,//左面
1,0,//前面
0,1,//右面
-1,0//后面
};
bool iswall(int x,int y,int i);//判断在(x,y)这个格子往i方向走是否是墙的函数
bool bfs();//核心函数
node tonext(node present,int i);//扩展函数,在当前节点上求与之相邻的有效的下一个结点

int main(){
cin>>n;
int i,j,k;
for(int x=0;x<n;x++){
    cin>>i>>j>>k;
    maze[i][j][k]=1;
}
cin>>start.px>>start.py;
cin>>start.mx>>start.my;
cin>>target.px>>target.py;//输入完毕
visited[start.px][start.py][start.mx][start.my]=1;//起始节点已被访问
q.push(start);//将起始节点加入队列

if(bfs()){
    cout<<"YES"<<endl;
}
else{
    cout<<"NO"<<endl;
}

return 0;
}



/*
广度遍历的大致思路都差不多,首先是访问队列头部,并将其出队列,看此节点是否为我们的目标节点,
如果是,则返回,如果不是,则拓展。拓展后的结点如果符合条件,就入队。

*/
bool bfs(){
while(!q.empty()){
    node top_node=q.front();//取出栈顶
    q.pop();
    //开始扩展
    //先判断栈顶元素是否是出口,若是,则返回true,否则继续扩展
    if(top_node.px==target.px &&top_node.py==target.py){
        return true;
    }
        for(int i=0;i<4;i++){
        node next_node=tonext(top_node,i);
        if(next_node.useful==1){
            q.push(next_node);

        }
    }


}


}

node tonext(node present,int i)//i=0代表向左走,i=1表示向前走,i=2表示向右走,i=3表示向后走
{
   node next_node;
   next_node.px=present.px+direction[i][0];//更新人的位置
   next_node.py=present.py+direction[i][1];
   if(next_node.px<0||next_node.px>5||next_node.py<0||next_node.py>5||iswall(present.px,present.py,i)){//判断人的位置是否有效
    next_node.useful=0;//如果人在这个方向走不通,则直接返回。
    return next_node;
   }
   else{
        next_node.mx=present.mx;//木乃伊更新前的位置信息
        next_node.my=present.my;

            for(int s=0;s<2;s++){//木乃伊可以走两步,每走一步就判断一次,总是先是跟人在同一列,然后再去同一行。
                if(next_node.my<next_node.py &&!iswall(next_node.mx,next_node.my,2)){
                   next_node.my++;}
                else if(next_node.my >next_node.py&&!iswall(next_node.mx,next_node.my,0)){
                    next_node.my--;
                }
                else if(next_node.my==next_node.py){
                    if(next_node.mx<next_node.px&&!iswall(next_node.mx,next_node.my,1)){
                        next_node.mx++;
                    }
                    else if(next_node.mx>next_node.px&&!iswall(next_node.mx,next_node.my,3)){
                        next_node.mx--;
                    }
                    else if(next_node.mx==next_node.px){
                        next_node.useful=0;
                        return next_node;
                    }
                }
 }
 if(next_node.mx==next_node.px&&next_node.my==next_node.py){//更新完木乃伊的位置之后,在判断一下是否此刻木乃伊走到了人的位置,如果是,则直接返回
    next_node.useful=0;
    return next_node;
 }
 if(visited[next_node.px][next_node.py][next_node.mx][next_node.my]==1){//如果更新完之后的点曾经已经访问过,则无效,相当于绕了一个大圈,又回到了曾经走过的点
    next_node.useful=0;
    return next_node;
 }
 else{
    visited[next_node.px][next_node.py][next_node.mx][next_node.my]=1;//否则的话,将这点记录为已访问,将结点置为有效。
    next_node.useful=1;
 }
   }
}




bool iswall(int x,int y,int i){
switch(i)
    {
        case 0:
            return maze[x][y-1][1];

        case 1:
            return maze[x-1][y][0];

        case 2:
            return maze[x][y][1];

        case 3:
            return maze[x][y][0];
    }
    return 0;


}
//----参考 夏至夏至520----//
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值