hdu 1429 胜利大逃亡(续)

二进制状态压缩+BFS。对于每一个点记录所有钥匙状态下最少的时间。如果这个点这个钥匙状态没有走过或者走过了但是时间花的少了,那么就走过去。

 

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 22;
int sx, sy, ex, ey;
char mapp[maxn][maxn];
int tz[maxn][maxn][1 << 10];//记录该状态下最少的时间
int dir[4][2] = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } };

struct abc{
    int key[15];
    int t, x, y;
    int zt;
}dt[500001];

int main()
{
    int n, m, t;
    while (~scanf("%d%d%d", &n, &m, &t))
    {
        getchar();
        int i, j, h;
        for (i = 1; i <= n; i++) for (j = 1; j <= m; j++) for (h = 0; h < 1 << 10; h++) tz[i][j][h] = 999999999;
        for (i = 1; i <= n; i++)
        {
            for (j = 1; j <= m; j++)
            {
                scanf("%c", &mapp[i][j]);
                if (mapp[i][j] == '@') sx = i, sy = j;
                else if (mapp[i][j] == '^') ex = i, ey = j;
            }
            getchar();
        }
        dt[0].x = sx; dt[0].y = sy; dt[0].t = 0, dt[0].zt = 0;
        for (i = 'a'; i <= 'j'; i++) dt[0].key[i - 'a'] = 0;
        int b = 0, k, flag = 0;
        for (i = 0; i <= b; i++)
        {

            if ((dt[i].t) % t == 0)
            {
                dt[i].x = sx;
                dt[i].y = sy;
            }

            if (dt[i].x == ex&&dt[i].y == ey)
            {
                flag = 1;
                printf("%d\n", dt[i].t);
                break;
            }
            for (k = 0; k < 4; k++)
            {
                int xx = dt[i].x + dir[k][0];
                int yy = dt[i].y + dir[k][1];
                if (xx >= 1 && xx <= n)
                {
                    if (yy >= 1 && yy <= m)
                    {
                        //如果是门
                        if (mapp[xx][yy] >= 'A'&&mapp[xx][yy] <= 'J')
                        {
                            if (dt[i].key[mapp[xx][yy] + 32 - 'a'] == 1)//如果有钥匙
                            {
                                if (tz[xx][yy][dt[i].zt] == 999999999 || dt[i].t + 1 < tz[xx][yy][dt[i].zt])
                                {
                                    b++;
                                    tz[xx][yy][dt[i].zt] = dt[i].t + 1;
                                    for (h = 'a'; h <= 'j'; h++) dt[b].key[h - 'a'] = dt[i].key[h - 'a'];
                                    dt[b].zt = dt[i].zt;
                                    dt[b].t = dt[i].t + 1;
                                    dt[b].x = xx; dt[b].y = yy;
                                }
                            }
                        }
                        //如果是钥匙
                        else if (mapp[xx][yy] >= 'a'&&mapp[xx][yy] <= 'j')
                        {
                            int sumzt = 0;
                            for (h = 'a'; h <= 'j'; h++)
                            {
                                if (h != mapp[xx][yy])
                                    sumzt = sumzt + dt[i].key[h - 'a'] * pow(2.0, h - 'a');
                                else if (h == mapp[xx][yy])
                                    sumzt = sumzt + 1 * pow(2.0, h - 'a');
                            }
                            if (tz[xx][yy][sumzt] == 999999999 || dt[i].t + 1 < tz[xx][yy][sumzt])
                            {
                                b++;
                                tz[xx][yy][dt[i].zt] = dt[i].t + 1;
                                for (h = 'a'; h <= 'j'; h++)
                                {
                                    if (h != mapp[xx][yy])
                                        dt[b].key[h - 'a'] = dt[i].key[h - 'a'];
                                    else if (h == mapp[xx][yy])
                                        dt[b].key[h - 'a'] = 1;
                                }
                                dt[b].zt = sumzt;
                                dt[b].t = dt[i].t + 1;
                                dt[b].x = xx; dt[b].y = yy;
                            }
                        }
                        //如果是终点或者路
                        else if (mapp[xx][yy] == '^' || mapp[xx][yy] == '.' || mapp[xx][yy] == '@')
                        {
                            if (tz[xx][yy][dt[i].zt] == 999999999 || dt[i].t + 1 < tz[xx][yy][dt[i].zt])
                            {
                                b++;
                                tz[xx][yy][dt[i].zt] = dt[i].t + 1;
                                for (h = 'a'; h <= 'j'; h++) dt[b].key[h - 'a'] = dt[i].key[h - 'a'];
                                dt[b].zt = dt[i].zt;
                                dt[b].t = dt[i].t + 1;
                                dt[b].x = xx; dt[b].y = yy;
                            }
                        }
                    }
                }
            }
        }
        if (!flag) printf("-1\n");
    }
    return 0;
}

 

posted @ 2015-04-18 07:45  Fighting_Heart  阅读(180)  评论(0编辑  收藏  举报