状态压缩记录当前拿到了哪些钥匙, 然后暴力搜索。
搞了好几个小时, 一开始也不知道哪里错了, 最后A了也不知道一开始哪里有问题。
#include <iostream> #include <vector> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <map> #include <set> #include <string> #include <queue> #include <stack> #include <bitset> using namespace std; #define pb(x) push_back(x) #define ll long long #define mk(x, y) make_pair(x, y) #define lson l, m, rt<<1 #define mem(a) memset(a, 0, sizeof(a)) #define rson m+1, r, rt<<1|1 #define mem1(a) memset(a, -1, sizeof(a)) #define mem2(a) memset(a, 0x3f, sizeof(a)) #define rep(i, n, a) for(int i = a; i<n; i++) #define fi first #define se second typedef pair<int, int> pll; const double PI = acos(-1.0); const double eps = 1e-8; const int mod = 1e9+7; const int inf = 1061109567; const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; const int maxn = 201; int n, m, cnt, g[maxn][maxn]; bool vis[maxn][maxn][1<<7][4], used[maxn][maxn][1<<7]; char s[maxn][maxn]; struct node { int x, y, step, key; node(){} node(int _x, int _y, int _step, int _key): x(_x), y(_y), step(_step), key(_key){} }; queue <node> q; int check(int x, int y) { if(x>=0&&x<n&&y>=0&&y<m) return 1; return 0; } int judge(int x, int y) { if(x == 1) return 0; if(x == -1) return 1; if(y == 1) return 2; if(y == -1) return 3; } void bfs(int x, int y) { mem(vis); mem(used); while(!q.empty()) q.pop(); used[x][y][0] = 1; q.push(node(x, y, 0, 0)); while(!q.empty()) { node temp = q.front(); q.pop(); int x = temp.x, y = temp.y, tmpx, tmpy; for(int i = 0; i < 4; i++) { int dirx = dir[i][0], diry = dir[i][1]; tmpx = x, tmpy = y; int key = temp.key; node tmp = temp; if(!check(tmpx+dirx, tmpy+diry) || s[tmpx+dirx][tmpy+diry]=='#') continue; while(1) { if(s[tmpx][tmpy] == 'L') dirx = 0, diry = -1; if(s[tmpx][tmpy] == 'R') dirx = 0, diry = 1; if(s[tmpx][tmpy] == 'U') dirx = -1, diry = 0; if(s[tmpx][tmpy] == 'D') dirx = 1, diry = 0; int tmpdir = judge(dirx, diry); if(vis[tmpx][tmpy][tmp.key][tmpdir]) break; vis[tmpx][tmpy][tmp.key][tmpdir] = 1; if(s[tmpx][tmpy] == 'E' && key == (1<<cnt)-1) { printf("%d ", temp.step+1); return ; } if(s[tmpx][tmpy] == 'K') key |= g[tmpx][tmpy]; if(check(tmpx+dirx, tmpy+diry)) { if(s[tmpx+dirx][tmpy+diry] == '#') { tmp.x = tmpx; tmp.y = tmpy; tmp.step++; tmp.key = key; q.push(tmp); used[tmpx][tmpy][tmp.key] = 1; break; } else { tmpx += dirx; tmpy += diry; } } else { break; } } } } puts("-1"); return ; } void solve() { cnt = 0; int x, y; for(int i = 0; i < n; i++) { for(int j = 0; j < m; j++) { if(s[i][j] == 'S') x = i, y = j; if(s[i][j] == 'K') { g[i][j] = 1<<cnt; cnt++; } } } bfs(x, y); } void read() { for(int i = 0; i < n; i++) scanf("%s", s[i]); } int main() { while(scanf("%d%d", &n, &m)!=EOF) { read(); solve(); } return 0; }