天天写算法之(BFS+状态压缩)胜利大逃亡(续)

地址: 点击打开链接
这个题目有几个很坑的地方,首先是我们需要开多一维,记录带钥匙走每一个块,和不带钥匙走是不一样的,所以我们多记录了一个。另外,不只是"."能走,“@”也能走。另外,每个状态查看vis的时候,需要查看走到这一状态时的状态,因此这个时候key的携带数量也会更新(但是要注意,不是啥都更新,拿到钥匙的时候,更新一下,看看vis是不是有过,但是没有说开门消耗钥匙,这个很关键),最后一个点,明明给了20*20最大的迷宫,但却要开到50*50才能过,哎,神坑啊。

代码如下:

#include<iostream>
#include<cstdio>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std ;
char  Map[50][50];
int t ,m , n,sx,sy;
int vis[50][50][2000];
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
struct Node{
    int x ,y,step ;
    int key ;
    bool check()
    {
        if(x>=0&&x<m&&y>=0&&y<n)
            return true ;
        return false ;
    }
};
int  bfs(){
    Node a ,temp;
    a.x =sx ;a.key = 0;
    a.y =sy;
    a.step=0;
    queue<Node> que ;
    que.push(a);
    vis[sx][sy][0]=1;
    while(!que.empty())
    {
        a = que.front();
        que.pop();
       // cout << "a : "<<a.x <<"  " << a.y <<endl;
        if(a.step>=t)
            return -1 ;
        if(Map[a.x][a.y]=='^')
            return a.step ;
        for(int i = 0 ; i < 4 ; i ++)
        {
            temp = a ;
            temp.x+=dir[i][0];
            temp.y+=dir[i][1];
            temp.step++;

            if(temp.check()&&Map[temp.x][temp.y]!='*')
            {
                //cout << temp.x <<"   " << temp.y <<"  " << temp.key<<endl;
                if(Map[temp.x][temp.y]>='a'&&Map[temp.x][temp.y]<='z')
                {

                    int tt= temp.key|(1<<(Map[temp.x][temp.y]-'a'));
                    if( !vis[temp.x][temp.y][tt])
                    {
                        temp.key =tt ;
                        vis[temp.x][temp.y][temp.key] =1;
                        que.push(temp);
                    }
                }else if(Map[temp.x][temp.y]>='A'&&Map[temp.x][temp.y]<='Z')
                {
                    int kt= temp.key&(1<<(Map[temp.x][temp.y]-'A'));
                    if(kt>0&&!vis[temp.x][temp.y][temp.key])
                    {
                        vis[temp.x][temp.y][temp.key] =1;
                        que.push(temp);
                    }
                }else
                {
                    if(!vis[temp.x][temp.y][temp.key])
                    {

                        vis[temp.x][temp.y][temp.key] =1;
                        que.push(temp);
                    }
                }
            }
        }
    }
    return -1;
}


int main(){
    int i,j;
    while(~scanf("%d%d%d",&m,&n,&t))
    {

        memset(vis,0,sizeof(vis));
        for(i = 0 ; i <m ; i ++)
        {
            for(j = 0 ; j <n ; j ++)
            {
                cin>>Map[i][j];
                if(Map[i][j]=='@')
                {
                    sx = i ;sy = j ;
                }
            }
        }
        printf("%d\n",bfs());

    }
}

猜你喜欢

转载自blog.csdn.net/qq_36616268/article/details/80532380