这道题的钥匙只有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;
}