HDU 1429 胜利大逃亡(续)(状压bfs)

与其他bfs不同的是这种题需要用二进制来保存钥匙这个状态,需要多用一维数组来保存。。

可以通过位运算  | “拾取钥匙”, & “匹配钥匙”。

#include "string"
#include "iostream"
#include "cstdio"
#include "cmath"
#include "set"
#include "queue"
#include "vector"
#include "cctype"
#include "sstream"
#include "cstdlib"
#include "cstring"
#include "stack"
//#include "ctime"
#include "algorithm"
#define pa pair<int,int>
#define Pi M_PI
#define INF 0x3f3f3f3f
#define INFL 0x3f3f3f3f3f3f3f3fLL
using namespace std;
typedef long long LL;
const int M=55;

struct Node
{
    int x, y;
    int kind;
    int t;
} star;

int n, m, time;
int dis[4][2] = {1, 0, 0, -1, -1, 0, 0, 1};
char map[21][21];
bool mark[20][20][1100];


int BFS()
{
    int i, j, kind, temp, t;
    struct Node node, next;
    queue<Node> Q;

    star.kind = 0;
    star.t = 0;
    Q.push(star);
    mark[star.x][star.y][0] = true;

    while(!Q.empty())
    {
        node = Q.front();

        Q.pop();

        kind = node.kind;
        t = node.t;

        if( t % time == 0 && t != 0)
        {
            node.x = star.x;
            node.y = star.y;
        }

        if( map[node.x][node.y] == '^')
            return node.t;

        for( i = 0 ; i < 4 ; i++)
        {
            next.x = node.x + dis[i][0];
            next.y = node.y + dis[i][1];
            next.kind = kind;

            if( next.x < 0 || next.y < 0 || next.x >= n || next.y >= m)
                continue;

            if( map[next.x][next.y] == '*' || mark[next.x][next.y][next.kind] == true)
                continue;

            next.t = t + 1;

            if( islower(map[next.x][next.y]))
            {
                j = map[next.x][next.y] - 'a';
                if( (kind & (1 << j) ) == 0)  //存储钥匙
                    next.kind = kind + (1 << j);
            }
            else if( isupper( map[next.x][next.y]) )
            {
                j = map[next.x][next.y] - 'A';
                temp = kind >> j;
                if( (temp & 1 ) == 0)    //判断钥匙能匹配不
                    continue;
                next.kind = kind;
            }

            mark[next.x][next.y][next.kind] = true;
            Q.push(next);
        }
    }
    return -1;
}


int main()
{
    int i, j, k, ans;
    k = 0;

    while(~ scanf("%d%d%d", &n, &m, &time))
    {
        memset( mark, 0, sizeof(mark));

        for( i = 0 ; i < n ; i++)
            {
                for( j = 0 ; j < m ; j++)
                {
                    cin>>map[i][j];
                    if( map[i][j] == '@')
                    {
                        star.x=i;
                        star.y=j;
                    }

               }
           }
        ans = BFS();

        printf("%d\n", ans);
    }
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值