📅  最后修改于: 2023-12-03 15:12:47.442000             🧑  作者: Mango
在一个城市里,有一些门需要打开才能通过。门的状态是不同的,有的门可以直接打开,有的门需要钥匙才能打开。每个人都有一把钥匙,但是钥匙只能开一扇门。这个城市的地图信息存在一个矩阵里,地图中,1代表可以直接通过的门,0代表需要钥匙才能通过的门,S代表起点,E代表终点,'.'代表可以直接通过的空地。假设有一个人位于起点,能否到达终点?
注意:
如果可以到达终点,输出"YES",否则输出"NO"。
5 5
0 S . 1 0
1 . 0 . 1
0 . 1 0 0
1 . E 1 1
0 1 0 . 0
YES
可以用BFS遍历整个地图,需要记录当前位置、当前拥有的钥匙以及已经走过的步数,如果当前位置为终点,则返回“YES”,否则继续搜索。遇到门时,如果拥有钥匙则直接通过,否则需要先回到之前拾取钥匙的位置再获取钥匙。
#include<iostream>
#include<queue>
#include<string.h>
using namespace std;
const int N = 25;
int n, m;
char g[N][N];
bool st[N][N][1 << 6];
typedef struct node{
int x, y, status, step;
}node;
// 上下左右方向的坐标增量
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
int bfs(int sx, int sy){
queue<node> q;
node cur;
cur.x = sx, cur.y = sy, cur.status = 0, cur.step = 0;
q.push(cur);
st[sx][sy][0] = true;
while(q.size()){
cur = q.front();
q.pop();
if(g[cur.x][cur.y] == 'E') return cur.step;
for(int i = 0; i < 4; i++){
int nx = cur.x + dx[i], ny = cur.y + dy[i];
int status = cur.status;
if(nx < 0 || nx >= n || ny < 0 || ny >= m || g[nx][ny] == '#') continue;
// 门
if(g[nx][ny] >= 'A' && g[nx][ny] <= 'F' && !(status >> (g[nx][ny] - 'A') & 1)) continue;
// 钥匙
if(g[nx][ny] >= 'a' && g[nx][ny] <= 'f') status |= 1 << (g[nx][ny] - 'a');
if(!st[nx][ny][status]){
node next_node;
next_node.x = nx, next_node.y = ny, next_node.status = status, next_node.step = cur.step + 1;
q.push(next_node);
st[nx][ny][status] = true;
}
}
}
return -1;
}
int main(){
int sx, sy;
cin >> n >> m;
memset(st, false, sizeof(st));
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
cin >> g[i][j];
if(g[i][j] == 'S') sx = i, sy = j;
}
}
cout << (bfs(sx, sy) == -1 ? "NO" : "YES") << endl;
return 0;
}