广搜并记录状态,通过扩展标记实现
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
char map[22][22];
bool vis[22][22][1024];
int n, m, t, sx, sy, sz;
int dirx[] = { 1,-1,0,0 };
int diry[] = { 0,0,1,-1 };
struct Node
{
int x, y, cost, key;
};
int bfs()
{
queue<Node>Q;
Node a, e;
memset(vis, false, sizeof(vis));
a.x = sx;
a.y = sy;
a.cost = 0;
a.key = 0;
vis[a.x][a.y][a.key]=true;
Q.push(a);
while (!Q.empty())
{
a = Q.front();
Q.pop();
if (map[a.x][a.y] == '^'&&a.cost < t)
{
return a.cost;
}
if (a.cost >= t)
{
return -1;
}
for (int i = 0;i < 4;i++)
{
e.key = a.key;
e.x = a.x + dirx[i];
e.y = a.y + diry[i];
e.cost = a.cost + 1;
if (e.x >= 0 && e.x < n && e.y >= 0 && e.y < m && map[e.x][e.y] != '*')
{
if (map[e.x][e.y] >= 'A'&&map[e.x][e.y] <= 'J')
{
int key = (map[e.x][e.y] - 'A');
if (((e.key >> key) & 1) && !vis[e.x][e.y][e.key])
{
vis[e.x][e.y][e.key]=true;
Q.push(e);
}
}
else if (map[e.x][e.y] >= 'a'&&map[e.x][e.y] <= 'j')
{
int key = (1 << (map[e.x][e.y] - 'a'));
e.key = (e.key | key);
if (!vis[e.x][e.y][e.key])
{
vis[e.x][e.y][e.key]=true;
Q.push(e);
}
}
else
{
if (!vis[e.x][e.y][e.key])
{
vis[e.x][e.y][e.key]=true;
Q.push(e);
}
}
}
}
}
return -1;
}
int main()
{
while (~scanf("%d %d %d", &n, &m, &t))
{
for (int i = 0;i < n;i++)
{
scanf("%s", map[i]);
for (int j = 0;j < m;j++)
if (map[i][j] == '@') sx = i, sy = j;
}
printf("%d\n", bfs());
}
return 0;
}