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;

}

 

你可能感兴趣的:(HDU)