用BFS解決迷宮最短路徑問題
迷宮問題中,有很大一部分可以用BFS來解。解決這類問題可以很大地提升能力與技巧,這篇文章是基於一個簡單例項展開來講的
例題:
第一行兩個整數n, m,為迷宮的長寬。
接下來n行,每行m個數為0或1中的一個。0表示這個格子可以通過,1表示不可以。假設你現在已經在迷宮座標(1,1)的地方,即左上角,迷宮的出口在(n,m)。每次移動時只能向上下左右4個方向移動到另外一個可以通過的格子裡,每次移動算一步。資料保證(1,1),(n,m)可以通過。
輸出格式
第一行一個數為需要的最少步數K。
第二行K個字元,每個字元∈{U,D,L,R},分別表示上下左右。如果有多條長度相同的最短路徑,選擇在此表示方法下字典序最小的一個。
樣例輸入
Input Sample 1:
3 3
0 0 1
1 0 0
1 1 0
Input Sample 2:
3 3
0 0 0
0 0 0
0 0 0
樣例輸出
Output Sample 1:
4
RDRD
Output Sample 2:
4
DDRR
BFS,屬於一種盲目搜尋法,目的是系統地展開並檢查圖中的所有節點,以找尋結果。換句話說,它並不考慮結果的可能位置,徹底地搜尋整張圖,直到找到結果為止。
虛擬碼
queue.add(起點);
while(佇列不為空){
取出隊首點
if(如果為終點)
結束
//不為終點,繼續向下走
for(方向)
...
}
- 下面貼上例題的程式碼
public class maze {
static int[][] one = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } };//上下左右移動座標的變化
static String[] nextpath = { "U", "D", "L", "R" };//上下左右移動的表示
static class point {//點類記錄當前座標,步數,路徑
int x, y, step;//step表示從出發到當前點經過幾步
String path;//path表示從出發到當前點經過路徑
public point(int x, int y, int step, String path) {
this .x = x;
this.y = y;
this.step = step;
this.path = path;
}
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int m = in.nextInt();
int[][] mazeArray = new int[n][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
mazeArray[i][j] = in.nextInt();
}
}
bfs(mazeArray, n, m);
}
//按字典序較小選擇路徑
public static boolean comparePath(String A, String B) {
char[] arrayA = A.toCharArray();
char[] arrayB = B.toCharArray();
for (int i = 0, len = A.length(); i < len; i++) {
if (arrayA[i] < arrayB[i])
return false;
}
return true;
}
//判斷點是否出界或被訪問過
public static boolean validatePoint(int[][] matrix, point a) {
int n = matrix.length - 1, m = matrix[0].length - 1;
if (a.x < 0 || a.x > n || a.y < 0 || a.y > m || matrix[a.x][a.y] == 1)
return false;
return true;
}
//搜尋
static void bfs(int[][] mazeArray, int n, int m) {
ArrayList<point> list = new ArrayList<point>();
list.add(new point(0, 0, 0, ""));//向佇列中加入第一個點
int minStep = Integer.MAX_VALUE;//最小步數
String minPath = "";//最短路徑
while (list.size() != 0) {
point currentPoint = list.get(0);//當佇列中有點時,取出點比較是否為終點
list.remove(0);//刪除該點
if (currentPoint.x == n - 1 && currentPoint.y == m - 1) {
if (minStep > currentPoint.step) {
minStep = currentPoint.step;
minPath = currentPoint.path;
} else if (minStep == currentPoint.step) {
if (comparePath(minPath, currentPoint.path)) {
minPath = currentPoint.path;
}
}
continue;
}
//如果不是終點,依次嘗試訪問上下左右,並加入佇列繼續迴圈
for (int i = 0; i < 4; i++) {
int x = currentPoint.x + one[i][0];
int y = currentPoint.y + one[i][1];
int step = currentPoint.step + 1;
String path = currentPoint.path + nextpath[i];
point nextPoint = new point(x, y, step, path);
if (validatePoint(mazeArray, currentPoint)) {
list.add(nextPoint);
mazeArray[x][y] = 1; //mark as 1 to bypass select next time
}
}
}
System.out.println(minPath + "\n" + minStep);//迴圈結束輸出最短步數及路徑
return;
}
}
執行結果
3 3
0 1 0
0 1 0
0 0 0
DDRR
4
- 如果無通路則會輸出Integer.Max_Value
相關推薦
用BFS解決迷宮最短路徑問題
迷宮問題中,有很大一部分可以用BFS來解。解決這類問題可以很大地提升能力與技巧,這篇文章是基於一個簡單例項展開來講的例題: 第一行兩個整數n, m,為迷宮的長寬。 接下來n行,每行m個數為0或1中的一個。0表示這個格子可以通過,1表示不可以。假設你現在已經在迷宮座標(1,1)
bfs poj3984 迷宮最短路徑且輸出路徑
題意: 定義一個二維陣列: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0,
BFS和DFS的差別,BFS實現迷宮最短路徑
BFS能夠求得最短路徑,因為BFS每進行一次相當於當前的路徑長度。對於一個N*N矩陣,BFS最多執行n*n次。 深度優先搜尋相當於一個人在走迷宮,廣搜相當於是無窮人沿著不同方向走(因為每條路都同時有人走)。 DFS相當於是一個下壓棧。是先進後出的原則(如
BFS+優先佇列——迷宮最短路徑——兩種最優方法比較及詳細圖解
http://blog.csdn.net/qq_36523667/article/details/78638354 這個連結裡是一道迷宮題。用到了BFS+優先佇列。 我一直百思不得其解優先佇列到底優先在哪了?我感覺和直接bfs沒啥區別?後來證明做法不一樣,思路也不一樣。
迷宮最短路徑長度bfs
#include<stdio.h> #include<iostream> using namespace std; struct note { int x;//橫座標 int y;//縱座標 int f;//父親在佇列中的編號,用於求輸出路
迷宮最短路徑dfs和bfs程式碼分析
dfs用遞迴一步步試探,在所有路徑中選出最短的一條路徑 程式碼: //0是路,1是牆 #include<iostream> #include<algorithm> using
迷宮最短路徑問題(BFS)
別人部落格上看到的一道題:給定一個大小為N*M的迷宮,由通道(‘.’)和牆壁(‘#’)組成,其中通道S表示起點,通道G表示終點,每一步移動可以達到上下左右中不是牆壁的位置。試求出起點到終點的最小步數。(本題假定迷宮是有解的)(N,M<=100) 原地址:
BFS迷宮最短路徑模板
oid pop print ios int pair 出口 最短路 bfs #include<iostream> #include<queue> #define INF 65535 using namespace std; int vis
求迷宮最短路徑【佇列+回溯】
求迷宮的最短路徑(0表示通路,1表示受阻) 問題:有一個迷宮,求從入口到出口的最短路徑,其中0表示通路,1表示受阻,規定向下是X軸,向右是Y軸 輸入:第一個數迷宮x軸的長度,第二個數迷宮y軸的長度,緊接著入口點的座標和出口的座標,之後
迷宮最短路徑問題解析
有一個二維陣列,0表示路,-1表示牆,求其中任意兩點的最短路徑。 我們先看,怎麼求一條路徑:求兩點路徑是一個數據結構上的典型的迷宮問題,很多資料結構的書上都有介紹,解決辦法如下: 從一點開始出發,向四個方向查詢,每走一步,把走過的點的值+1(即本節點值+1),防止重複行走,並把走過的點壓入堆疊
狄克斯特拉演算法,解決加權最短路徑問題--python實現
問題:尋找從起點到終點的最短路徑。 關係圖如下: 解決思路:建立三張散列表。graph 儲存關係圖;costs 儲存各個節點的開銷(開銷是指從起點到該節點的最小的權重);
Sicily. 迷宮最短路徑
Time Limit: 1sec Memory Limit:256MB Description 有一個矩形迷宮,入口和出口都確定為唯一的,且分佈在矩形的不同邊上。 現在讓你算出最短需要走多少步,才可以從入口走到出口。 Input 共N+1行,第一行為
資料結構::迷宮(二)--棧的一個應用(求迷宮最短路徑)
上篇文章我們知道求解迷宮通路的方法,但是一個迷宮有時是不止一條出路,在這些出路中,我們如何找到最短的那一條,這就是我今天要說的迷宮最短路徑問題。 (此處使用的圖): 【先來分析有什麼解決方案:】 1、方法一:我們如果採用上章中遞迴的方式,將所走的路用2標記起來
迷宮最短路徑演算法(使用佇列)
順便也把圖裡求迷宮最短路徑演算法貼出來,主要思想是利用佇列,採用廣度優先搜尋法,當第一次出現目的點時,中斷搜尋,並輸出路徑。程式還是主要使用的C語言,對於佇列操作我又重寫了下基本操作程式碼比如入隊、出隊等,沒辦法對C++不熟啊!! 個人認為需要說明的是:
關於棧與遞迴求解迷宮與迷宮最短路徑問題
一、棧實現迷宮問題: 問題描述:用一個二維陣列模擬迷宮,其中1為牆,0為通路,用棧方法判斷迷宮是否有出口,下圖為簡單模擬的迷宮: 思想: 1.首先給出入口點,如上圖入口點座標為{2,0}; 2.從入口點出發,在其上下左右四個方向試探,若為通路(值為0)時,則向前走,並將每
構建有向帶權圖用鄰接矩陣求最短路徑
#include <bits/stdc++.h> #include <limits> using namespace std; int main() { int tu[1
用棧解決迷宮問題(輸出所有路徑和最短路徑)
#include<iostream> #include<cstdio> using namespace std; #define M 4 //行數 #define N 4 //列數 #define MaxSize 100 //棧最多元素個數 int m
HPU暑期第五次積分賽 - G-迷宮(BFS+最短路徑)
題目 程式碼 #include <iostream> #include <cstdio> #include <queue> #include <cstring> using namespace std; int mp[110][11
poj2251(bfs尋找最短路徑,三位迷宮)
題目連結:http://poj.org/problem?id=2251 Dungeon Master Time Limit: 1000MS Memory Limit: 65536K
【DFS】 用 棧 求迷宮問題的所有路徑和最短路徑
1++.cpp 方法來源 https://blog.csdn.net/zhouchenghao123/article/details/83626222 博主 :ZAX1 ,部落格:用棧解決迷宮問題(輸出所有路徑和最短路徑) //【DFS】 用 棧