版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_32767041/article/details/86484282
Description
牛客网 2018校招真题 迷宫寻路
Solving Ideas
node.keys
的二进制表示代表钥匙的拾取状态,例如:
(以下的数字为二进制,省略前导0,该类型为int,完整位数为32)
初始时,没有拾取任何钥匙,node.keys = 0
假设现在从node
移动到node2
,且node2
位置有钥匙'a'
,通过更新 node2.keys = node.keys | (1 << (maze[nx][ny] - 'a')
来拾取该钥匙,此时node2.keys = 1
,代表已携带钥匙'a'
。
继续假设现在从node2
移动到node3
,且node3
位置有钥匙'd'
,通过更新 node3.keys = node2.keys | (1 << (maze[nx][ny] - 'a')
来拾取该钥匙,此时node3.keys = 1001
,代表已携带钥匙'a'
和 'd'
。
…
同理若keys = 0101 1010
,则当前位置已有钥匙'b', 'd', 'e', 'g'
visit[i][j][keys]
: 表示在maze[i][j]
位置且携带钥匙状态为keys
的情况是否已经访问过
Solution
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
class Node {
int x;
int y;
int keys;
int step;
Node(int x, int y, int keys, int step) {
this.x = x;
this.y = y;
this.keys = keys;
this.step = step;
}
}
/**
* @author wylu
*/
public class Main {
public static int[][] dir = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
public static int m;
public static int n;
public static char[][] maze;
public static boolean[][][] visit;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] strs = br.readLine().split(" ");
m = Integer.parseInt(strs[0]);
n = Integer.parseInt(strs[1]);
maze = new char[m][n];
visit = new boolean[m][n][1024];
for (int i = 0; i < m; i++) {
maze[i] = br.readLine().toCharArray();
}
int res = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (maze[i][j] == '2') {
res = bfs(i, j);
}
}
}
System.out.println(res);
}
private static int bfs(int x, int y) {
LinkedList<Node> queue = new LinkedList<Node>();
queue.add(new Node(x, y, 0, 0));
visit[x][y][0] = true;
while (!queue.isEmpty()) {
Node node = queue.poll();
for (int i = 0; i < 4; i++) {
int nx = node.x + dir[i][0], ny = node.y + dir[i][1];
if (nx < 0 || nx >= m || ny < 0 || ny >= n || maze[nx][ny] == '0') continue;
if (maze[nx][ny] == '3') return node.step + 1;
//无法开门
if (maze[nx][ny] >= 'A' && maze[nx][ny] <= 'Z'
&& ((node.keys & (1 << (maze[nx][ny] - 'A'))) == 0)) continue;
int keys = node.keys;
if (maze[nx][ny] >= 'a' && maze[nx][ny] <= 'z') {
keys = node.keys | (1 << (maze[nx][ny] - 'a'));
}
if (!visit[nx][ny][keys]) {
visit[nx][ny][keys] = true;
queue.offer(new Node(nx, ny, keys, node.step + 1));
}
}
}
return -1;
}
}