牛客2018校招 1. 拼多多 迷宮尋路

題目描述
假設一個探險家被困在了地底的迷宮之中,要從當前位置開始找到一條通往迷宮出口的路徑。迷宮能夠用一個二維矩陣組成,有的部分是牆,有的部分是路。迷宮之中有的路上還有門,每扇門都在迷宮的某個地方有與之匹配的鑰匙,只有先拿到鑰匙才能打開門。請設計一個算法,幫助探險家找到脫困的最短路徑。如前所述,迷宮是經過一個二維矩陣表示的,每一個元素的值的含義以下 0-牆,1-路,2-探險家的起始位置,3-迷宮的出口,大寫字母-門,小寫字母-對應大寫字母所表明的門的鑰匙

輸入描述:
迷宮的地圖,用二維矩陣表示。第一行是表示矩陣的行數和列數M和N
後面的M行是矩陣的數據,每一行對應與矩陣的一行(中間沒有空格)。M和N都不超過100, 門不超過10扇。
輸出描述:
路徑的長度,是一個整數

示例1
輸入
5 5
02111
01a0A
01003
01001
01111
輸出
7

看到這道題目,求脫困的最短路徑,首先就想到了bfs, 可是這裏有一點不一樣的是(難受的是):
1.他有10扇門,10把鑰匙,怎麼去拿鑰匙去開門,鑰匙和門怎麼對應?
2.一樣一個點,拿到鑰匙a,b,c的時候,和只拿到鑰匙b。這樣的時候明顯是不一樣的。
由於 : 這個時候,若是遇到了門A,拿到鑰匙a,b,c的時候,能夠打開,可是隻拿到鑰匙b的時候,不能打開。java

看評論,一個巧妙地作法是這樣的。
利用一個map[x][y][key] , key 用來記錄鑰匙的狀態,橫座標爲x,縱座標爲y,
鑰匙的狀態 就用二進制數表示 最多10 把鑰匙 那就是1024
好比我如今有第二把鑰匙和第四把鑰匙 那麼個人鑰匙狀態就是 0101000000 也就是 320node

代碼以下:算法

import java.util.*;

public class Main{
    
    static class Node{
        int x;
        int y;
        int key;
        int step;
        public Node(int x, int y, int key, int step){
            this.x = x;
            this.y = y;
            this.key = key;
            this.step = step;
        }
    }
    
    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        int N = in.nextInt();
        int M = in.nextInt();
        in.nextLine();
        char[][] G = new char[N][M];
        for (int i = 0;i< N;i++)
            G[i] = in.nextLine().toCharArray();
        for (int i = 0; i< N;i++){
            for (int j=0;j<M;j++){
                if (G[i][j] == '2'){
                    System.out.println(bfs(i,j, N, M, G));
                    return;
                }
            }
        }
    }
    
    private static int bfs(int si, int sj, int N, int M, char[][] G){
        Queue<Node> queue = new LinkedList<>();
        int[][][] mp = new int[101][101][1025];
        int[][] next = {{-1,0},{0,-1},{1,0},{0,1}};
        
        queue.offer(new Node(si,sj, 0, 0));
        while (!queue.isEmpty()){
            Node node = queue.poll();
            for (int i = 0; i < 4 ; i++){
                int x = node.x + next[i][0];
                int y = node.y + next[i][1];
                int key = node.key;
                if(x < 0 || x >= N || y < 0 || y >= M || G[x][y] == '0')    continue;
                else if (G[x][y] == '3')    return node.step +1;
                else if (G[x][y] <= 'z' && G[x][y] >= 'a')    key = key | (1 << (G[x][y] - 'a'));
                else if (G[x][y] <= 'Z' && G[x][y] >= 'A' && (key & (1 << G[x][y] - 'A') ) == 0)    continue;
                if (mp[x][y][key] == 0){
                    mp[x][y][key] = 1;
                    queue.offer(new Node(x,y,key,node.step + 1));
                }
            }
        }
        return -1;
    }
    
    
}
相關文章
相關標籤/搜索