牛客网 2018校招真题 拼多多 迷宫寻路

版权声明:本文为博主原创文章,未经博主允许不得转载。 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;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_32767041/article/details/86484282
今日推荐