当前位置: 代码迷 >> 综合 >> Hdu 1429 胜利大逃亡(续) (bfs+状态压缩)
  详细解决方案

Hdu 1429 胜利大逃亡(续) (bfs+状态压缩)

热度:29   发布时间:2023-09-20 18:33:20.0

这道题的钥匙只有10个,可以压成二进制

这里有有句非常关键的话

(k & door[x][y]) == door[x][y]

一开始以为只要(k & door[x][y]) ==1就可以了

后来发现如果door[x][y]为0的话,这句话就不对了。

所以要包含这里没有门的情况

所以要这么写

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cstring>
#define REP(i, a, b) for(int i = (a); i < (b); i++)
#define _for(i, a, b) for(int i = (a); i <= (b); i++)
using namespace std;const int MAXN = 25;
struct node { int x, y, step, key; };
int key[MAXN][MAXN], door[MAXN][MAXN], vis[MAXN][MAXN][1050];
int arr[MAXN][MAXN], sx, sy, ex, ey, n, m, t;
int dir[4][2] = {0, 1, 0, -1, -1, 0, 1, 0};bool judge(int x, int y, int k)
{if(!(0 <= x && x < n && 0 <= y && y < m)) return false;if(vis[x][y][k] || arr[x][y]) return false;if(!((k & door[x][y]) == door[x][y])) return false;return true;	
}int bfs()
{queue<node> q;q.push(node{sx, sy, 0, 0});vis[sx][sy][0] = 1;while(!q.empty()){node u = q.front(); q.pop();if(u.x == ex && u.y == ey) return u.step;REP(i, 0, 4){int x = u.x + dir[i][0], y = u.y + dir[i][1];if(!judge(x, y, u.key)) continue;int k = u.key | key[x][y];vis[x][y][k] = 1;q.push(node{x, y, u.step + 1, k});}}return 1e9;
}int main()
{while(~scanf("%d%d%d", &n, &m, &t)){memset(door, 0, sizeof(door));memset(key, 0, sizeof(key));memset(vis, 0, sizeof(vis));memset(arr, 0, sizeof(arr));REP(i, 0, n){char s[MAXN];scanf("%s", s);REP(j, 0, m){char ch = s[j];if(ch == '*') arr[i][j] = 1;if(ch == '@') sx = i, sy = j;if(ch == '^') ex = i, ey = j;if('a' <= ch && ch <= 'z' ) key[i][j] = 1 << (ch - 'a');if('A' <= ch && ch <= 'Z' ) door[i][j] = 1 << (ch - 'A');}}int ans = bfs();printf("%d\n", ans < t ? ans : -1);}return 0;
}