hdu 1429 胜利大逃亡(续) bfs+状态压缩

#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <queue>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL __int64
int n,m,t;
bool vis[21][21][1025];
int dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
char e[21][21];
struct node{
    int x,y,step,w;
}b;
queue<node>q;
int bfs(node a)
{
    memset(vis,false,sizeof(vis));
    a.step=a.w=0;
    vis[a.x][a.y][0]=true;
    while(!q.empty())q.pop();
    int i,j,k,xx,yy,step,w;
    q.push(a);
    while(!q.empty())
    {
        a=q.front();
        q.pop();
        if(a.step>=t-1)return -1;
        for(i=0;i<4;i++)
        {
            xx=a.x+dir[i][0];
            yy=a.y+dir[i][1];
            step=a.step+1;
            w=a.w;
            //汗,这里忘了vis,超内存,我还以为是我队列的缘故呢。。
            if(xx<0||yy<0||xx>=n||yy>=m||e[xx][yy]=='*'||vis[xx][yy][w])continue;
            if(e[xx][yy]=='^')return step;

            if(e[xx][yy]>='A'&&e[xx][yy]<='J')
            {
                j=e[xx][yy]-'A';
                if(((1<<j)&w)&&!vis[xx][yy][w])
                {
                    vis[xx][yy][w]=true;
                    b.x=xx;b.y=yy;b.step=step;b.w=w;
                    q.push(b);
                }
            }
            else if(e[xx][yy]>='a'&&e[xx][yy]<='j')
            {
                j=e[xx][yy]-'a';
                w=w|(1<<j);
                if(!vis[xx][yy][w])
                {
                    vis[xx][yy][w]=true;
                    b.x=xx;b.y=yy;b.step=step;b.w=w;
                    q.push(b);
                }
            }
            else
            {
                vis[xx][yy][w]=true;
                b.x=xx;b.y=yy;b.step=step;b.w=w;
                q.push(b);
            }
        }
    }
    return -1;
}
int main()
{
    while(scanf("%d%d%d",&n,&m,&t)!=EOF)
    {
        int i,j,k;
        node a;
        for(i=0;i<n;i++)
            scanf("%s",e[i]);
        for(i=0;i<n;i++)
        {
            for(j=0;j<m;j++)
            if(e[i][j]=='@'){a.x=i;a.y=j;}
        }
        printf("%d\n",bfs(a));
    }
    return 0;
}
/*
    状态压缩+bfs题
    vis[i][j][k]标记坐标为(i,j),钥匙状态为k(用10位二进制表示,每位对应一把钥匙)的状态。
    遇到牢门时,判断下钥匙状态中是否有钥匙。
    遇到钥匙时,改变钥匙状态
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值