HDU 1429

终于过了这道题

做的第一道位压缩


http://acm.hdu.edu.cn/showproblem.php?pid=1429


#include<stdio.h>
#include<iostream>
#include<math.h>
#include<stdlib.h>
#include<algorithm>
#include<vector>
#include<string.h>
#include<queue>
#include<malloc.h>

using namespace std;

int n, m, t;

int ans,num;

char s[22];

int sx, sy;

int dir[4][2] = { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } };//四个方向

int vis[22][22][1025];

struct Q
{
    int x;
    int y;
    char ele;
    int step;
    int nkeys;
}p[22][22];

int check(int x, int y)
{
    if (x>=0 && x<n && y>=0 && y<m)
        return 1;
    else
        return 0;
}

void bfs()
{
    memset(vis,0,sizeof(vis));
    queue <Q> q;
    Q qq, qqq;
    p[sx][sy].step = 0;
    p[sx][sy].nkeys = 0;

    vis[sx][sy][p[sx][sy].nkeys] = 1;

    q.push(p[sx][sy]);

    while (!q.empty())
    {
        qq = q.front();
        q.pop();

        if (p[qq.x][qq.y].ele == '^' && qq.step < t)
        {
            printf("%d\n",qq.step);
            return ;
        }
        else if ( p[qq.x][qq.y].ele == '^' && qq.step >= t )
        {
            printf("-1\n");
            return ;
        }

        for (int i = 0; i < 4;i++)
        {
            int x = qq.x+dir[i][0];
            int y = qq.y+dir[i][1];

            qqq = qq;
            qqq.x = x;
            qqq.y = y;

            if ( check(qqq.x, qqq.y)  &&  p[qqq.x][qqq.y].ele != '*'  &&  !vis[qqq.x][qqq.y][qqq.nkeys])
            {
                if (p[qqq.x][qqq.y].ele >= 'a' && p[qqq.x][qqq.y].ele <= 'j' )
                {
                    int key = 1 << (p[qqq.x][qqq.y].ele - 'a');

                    qqq.nkeys |= key;//拾取钥匙
                    if (!vis[qqq.x][qqq.y][qqq.nkeys])
                    {
                        qqq.step += 1;
                        vis[qqq.x][qqq.y][qqq.nkeys] = 1;
                        q.push(qqq);
                    }
                }
                else if (p[qqq.x][qqq.y].ele >= 'A' && p[qqq.x][qqq.y].ele <= 'J' )
                {
                    int key = 1 << (p[qqq.x][qqq.y].ele - 'A');

                    if ( (qqq.nkeys & key) )//检查手头是否有该门的钥匙
                    {
                        qqq.step += 1;
                        vis[qqq.x][qqq.y][qqq.nkeys] = 1;
                        q.push(qqq);
                    }
                }
                else 
                {
                    qqq.step += 1;
                    vis[qqq.x][qqq.y][qqq.nkeys] = 1;
                        q.push(qqq);
                }
            }
        }
    }
    printf("-1\n");
    return;
}

int main()
{
    while (scanf("%d %d %d", &n, &m, &t) != EOF)
    {
        num = 0;
        sx = sy = 0;
        for (int i = 0; i < n; i++)
        {
            scanf("%s",s);
            for (int j = 0; j < m; j++)
            {
                p[i][j].ele = s[j];
                p[i][j].step = 0 ;
                p[i][j].nkeys = 0 ;
                p[i][j].x = i;
                p[i][j].y = j;

                if (p[i][j].ele == '@')
                {
                    sx = i;
                    sy = j;
                }
            }
        }

        bfs();

    }
    return 0;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值