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