HDU 1429 胜利大逃亡(续)

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

int
n, m, t;
char
map[20][20];//地图
int
dir[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};//四个方向
bool
hash[20][20][1100];//三维表,走过的路径对应表的状态
int
keybin[10] = {1,2,4,8,16,32,64,128,256,512};//JIHGFEDCBA

struct
Node
{

    short
x, y, step, keystate;
    bool
key[10];
};


bool
operator < (Node a, Node b)
{

    return
a.step > b.step;
}


Node first, next;
void
init()
{

    int
i, j;
    for
(i = 0; i < n; ++i)
    {

        getchar();
        for
(j = 0; j < m; ++j)
        {

            scanf("%c", &map[i][j]);
            if
(map[i][j] == '@')
            {

                first.x = i;
                first.y = j;
            }
        }
    }

    memset(first.key, 0, sizeof(first.key));
    memset(hash, 0, sizeof(hash));
    first.step = 0;
    first.keystate = 0;
}


int
bfs()
{

    priority_queue <Node> Q;
    Q.push(first);

    while
(!Q.empty())
    {

        first = Q.top();
        Q.pop();

        if
(map[first.x][first.y] == '^')
        {

            return
first.step;
        }//为门,步数为零

        if
(first.step >= t)//*if not then get a TLE
        {
            return
-1;
        }

        for
(int i = 0; i < 4; ++i)
        {

            next = first;
            next.x = first.x + dir[i][0];
            next.y = first.y + dir[i][1];
            next.step = first.step + 1;
            if
(next.x >= 0 && next.x < n && next.y >= 0 && next.y < m
                &&
map[next.x][next.y] != '*')//不为墙
            {

                if
(map[next.x][next.y] >= 'A' && map[next.x][next.y] <= 'J')//情况1:为门
                {

                    if
(first.key[map[next.x][next.y]-'A'] &&
                        !
hash[next.x][next.y][next.keystate])//有对应门的钥匙,且没有走过,有一项不符则进行下方向
                    {

                        hash[next.x][next.y][next.keystate] = true;//标记为走过
                        Q.push(next);//下一个入队列
                    }
                }

                else if
(map[next.x][next.y] >= 'a' && map[next.x][next.y] <= 'j')//情况二:为钥匙
                {

                    int
state = next.keystate, k;//拿钥匙
                    k = map[next.x][next.y]-'a';
                    if
(!next.key[k])
                    {

                        state += keybin[k];
                    }

                    if
(!hash[next.x][next.y][state])//标记为走过
                    {

                        hash[next.x][next.y][state] = true;
                        next.key[k] = true;
                        next.keystate = state;//标记为走过
                        Q.push(next);//下一个入队
                    }
                   
                }

                else

                {

                    if
(!hash[next.x][next.y][next.keystate])//情况三:为路
                    {

                        hash[next.x][next.y][next.keystate] = true;//标记
                        Q.push(next);//入队
                    }
                }
            }
        }
    }

    return
-1;
}

int
main()
{

    while
(scanf("%d %d %d", &n, &m, &t) != EOF)
    {

        init();
        int
result = bfs();
        if
(result == -1 || result >= t)
        {

            puts("-1");
        }

        else

        {

            printf("%d/n", result);
        }
    }

    return
0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值