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; }