题目链接:
里面设置了一扇大门和钥匙,但是到底要不要走过大门还不一定所以要都搜一下,取要还是不要最小值.
经过大门的搜法是先搜钥匙,再删了门,最后从门搜到终点.
注意有可能拿不到钥匙.
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> P;
#define f first
#define s second
int H, W;
int vx[] = {0, 0, 1, -1};
int vy[] = {-1, 1, 0, 0};
int sx, sy, dx, dy, kx, ky, xx, yy;
bool used[505][505];
char maze[505][505];
int ans[505][505];
bool k[505][505];
int bfs(int goal)
{
queue<P> que;
que.push(P(sx, sy));
memset(used, 0, sizeof used);
memset(ans, 0, sizeof ans);
memset(k, 0, sizeof k);
while(!que.empty())
{
P head = que.front();
que.pop();
int x = head.f, y = head.s;
used[x][y] = true;
if(goal == 0 && x == dx && y == dy)
return ans[x][y];
else if(goal == 1 && x == kx && y == ky)
return ans[x][y];
for(int i = 0; i < 4; i++)
{
int nx = x + vx[i], ny = y + vy[i];
if(0 <= nx && nx < H && 0 <= ny && ny < W && maze[nx][ny] != 'W' && maze[nx][ny] != 'D' && !used[nx][ny])
{
ans[nx][ny] = ans[x][y] + 1;
que.push(P(nx, ny));
}
}
}
return -1;
}
int main()
{
while(scanf("%d%d", &H, &W) != EOF)
{
for(int i = 0; i < H; i++)
scanf("%s", maze[i]);
for(int i = 0; i < H; i++)
for(int j = 0; j < W; j++)
{
if(maze[i][j] == 'S')
{
sx = i;
sy = j;
}
if(maze[i][j] == 'K')
{
kx = i;
ky = j;
}
if(maze[i][j] == 'E')
{
dx = i;
dy = j;
}
if(maze[i][j] == 'D')
{
xx = i; yy = j;
}
}
int a = bfs(0);
int b = bfs(1);
sx = kx;
sy = ky;
maze[xx][yy] = '.';
int c = bfs(0);
if(a == -1 && b == -1)
printf("-1\n");
else if(a != -1 && b == -1)
printf("%d\n", a);
else if(a == -1 && b != -1 && c != -1)
printf("%d\n", c + b);
else if(a == -1 && c == -1)
printf("-1\n");
else if(a != -1 && b != -1 && c != -1)
printf("%d\n", min(a, b + c));
}
return 0;
}