仙島求藥(BFS迷宮尋找最短路徑)
下圖 顯示了一個迷陣的樣例及李逍遙找到仙藥的路線.
輸入 輸入有多組測試資料. 每組測試資料以兩個非零整數 M 和 N 開始,兩者均不大於20。M 表示迷陣行數, N 表示迷陣列數。接下來有 M 行, 每行包含N個字元,不同字元分別代表不同含義:
1) ‘@’:少年李逍遙所在的位置;
2) ‘.’:可以安全通行的方格;
3) ‘#’:有怪物的方格;
4) ‘*’:仙藥所在位置。
當在一行中讀入的是兩個零時,表示輸入結束。
輸出 對於每組測試資料,分別輸出一行,該行包含李逍遙找到仙藥需要穿過的最少的方格數目(計數包括初始位置的方塊)。如果他不可能找到仙藥, 則輸出 -1。 樣例輸入
8 8 [email protected]樣例輸出##...# #....#.# #.#.##.. ..#.###. #.#...#. ..###.#. ...#.*.. .#...### 6 5 .*.#. .#... ..##. ..... .#... [email protected] 9 6 .#..#. .#.*.# .####. ..#... ..#... ..#... ..#... #[email protected]## .#..#. 0 0
10 8 -1
之前寫了一個深搜,在做後面的題目時用深搜肯定超時超時超時,索性直接寫個廣搜,因為我感覺深搜好理解一些,一直遍歷一直遍歷找到最短的。廣搜就直接遍歷一次,使得下一次到達的點都是最小的。
1.從起點開始,先將其加入佇列,設定步數為0
2.從佇列首端取出位置,將從這個位置能夠到達的位置加入佇列,並且讓這些位置的距離為上一個位置的距離加上1
3.迴圈2直到從佇列首端取出的是終點
最簡單的理解方法就是畫圖,結合佇列的先進先出,每到達一個點
#include<iostream> #include<queue> using namespace std; typedef pair<int, int> P; int n, m, q1, q2, z1, z2; char a[21][21]; int pd(int i, int j){ if (i < 0 || j < 0 || i >= n || j >= m || a[i][j] == '#')//不能出邊界 return 0; return 1; } int main(){ while (1){ int map[21][21]; cin >> n >> m; if (n == 0 && m == 0) break; for (int i = 0; i < n; i++){ for (int j = 0; j < m; j++){ cin >> a[i][j]; map[i][j] = 1000; if (a[i][j] == '@'){ q1 = i; q2 = j; } if (a[i][j] == '*'){ z1 = i; z2 = j; } } } queue<P> que; map[q1][q2] = 0; que.push(P(q1, q2));//將起點入佇列 while (que.size()) { P p = que.front(); //取得頭元素 que.pop(); if (p.first == z1&&p.second == z2) break; if (pd(p.first + 1, p.second) && map[p.first + 1][p.second] == 1000){//如果地圖上某一點已經走過了,那就不用走了,肯定有別的方法到達它更短 map[p.first + 1][p.second] = map[p.first][p.second] + 1;//因為在每次處理的位置都是遞增的。走過的路不用走了,也映證了廣搜 que.push(P(p.first + 1, p.second)); } if (pd(p.first - 1, p.second) && map[p.first - 1][p.second] == 1000){ map[p.first - 1][p.second] = map[p.first][p.second] + 1; que.push(P(p.first - 1, p.second)); } if (pd(p.first, p.second + 1) && map[p.first][p.second + 1] == 1000){ map[p.first][p.second + 1] = map[p.first][p.second] + 1; que.push(P(p.first, p.second + 1)); } if (pd(p.first, p.second - 1) && map[p.first][p.second - 1] == 1000){ map[p.first][p.second - 1] = map[p.first][p.second] + 1; que.push(P(p.first, p.second - 1)); } } if (map[z1][z2] == 1000) printf("-1\n"); else printf("%d\n", map[z1][z2]); } return 0; }
先結合圖理解程式碼。有好的思想一起交流 實在不懂了就可以先看下:抓住那頭牛。這道題的廣搜就簡單很多 http://blog.csdn.net/qq_33193309/article/details/55260780
相關推薦
仙島求藥(BFS迷宮尋找最短路徑)
描述 少年李逍遙的嬸嬸病了,王小虎介紹他去一趟仙靈島,向仙女姐姐要仙丹救嬸嬸。叛逆但孝順的李逍遙闖進了仙靈島,克服了千險萬難來到島的中心,發現仙藥擺在了迷陣的深處。迷陣由M×N個方格組成,有的方格內
BFS (迷宮的最短路徑)
迷宮的最短路徑 給定一個大小為N * M 的迷宮。迷宮由通道和牆壁組成,每一步可以向鄰接的上下左右四格的通道移動。請求出從起點到終點所需的最小步數。請注意,本題假定從起點一定可以移動到終點 。 限制條件: N , M<=100 。( # . S G 分
無向圖的Dijkstra演算法(求任意一對頂點間的最短路徑)迪傑斯特拉演算法
public class Main{ public static int dijkstra(int[][] w1,int start,int end) { boolean[] isLable = new boolean[w1[0].length];//是否標上所有的號 i
一個例子讓你明白一個演算法-Dijkstra(求源點到各頂點最短路徑)
演算法思想 1.在一個圖中,把所有頂點分為兩個集合P,Q(P為最短路徑集合,Q為待選集合),用dis陣列儲存源點到各個頂點的最短路徑(到自身為0)。 2.初始化P集合,就是加入源點到該集合,並在ma
PAT 1111 —— Online Map(Dijkstra單源最短路徑)
題目注意事項: 迪傑斯特拉兩次: 第一次求最短的路程長度【順便記錄時間用時,以判斷長度相同的時候選擇時間短的】 第二次求最短的路程時間【順便記錄到達每個點的最短路徑所需要的點數,以判斷時間相同時候選擇點數少的】【注意:第一次求得時間記錄需要重新初始化以免錯誤】
仙島求藥(經典的BFS和DFS運用題)
原題目來自OpenJudge 下面的都是Java實現的 先看看思路比較簡單的BFS import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import j
(1)仙島求藥(lake.pas/c/cpp)
(1)仙島求藥(lake.pas/c/cpp) 【問題描述】 少年李逍遙的嬸嬸病了,王小虎介紹他去一趟仙靈島,向仙女姐姐要仙丹救嬸嬸。叛逆但孝順的李逍遙闖進了仙靈島,克服了千險萬難來到島的中心,發現仙藥擺在了迷陣的深處。迷陣由M×N個方格組成,有的方格內有可以瞬秒李逍遙的怪物,而有的方格內則
openjudge 2727:仙島求藥
現在 pan blog 安全 node 大於 所在 陣列 using 2727:仙島求藥 總時間限制:1000ms內存限制:65536kB描述少年李逍遙的嬸嬸病了,王小虎介紹他去一趟仙靈島,向仙女姐姐要仙丹救嬸嬸。叛逆但孝順的李逍遙闖進了仙靈島,克服了千險萬難來到島的中
仙島求藥
0kb step 長度 時間限制 代碼 是否 tput stream mina #include<iostream> #include<cmath> #include<cstdio> #include<algorithm>
poj 3984迷宮問題(bfs求最短路徑 類似並查集儲存上個節點 儲存最短路徑)
迷宮問題 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16343 Accepted: 9762 Description 定義一個二維陣列: int maze[5][5] = { 0,
2727:仙島求藥-Openjudge
2727:仙島求藥 描述 輸入 輸出 解析 2727:仙島求藥 描述 少年李逍遙的嬸嬸病了,王小虎介紹他去一趟仙靈島,向仙女姐姐要仙丹救嬸嬸。叛逆但孝順的李逍遙闖進了仙靈島,克服了千險萬難來到島
UVa 1599 理想路徑(反向BFS 求最短路徑 )
ack pan clu inf struct name esp turn pop 題意: 給定一個有重邊有自環的無向圖,n個點(2 <= n <= 100000), m條邊(1 <= m <= 200000), 每條邊有一個權值, 求從第一個點到n的
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
資料結構::迷宮(二)--棧的一個應用(求迷宮最短路徑)
上篇文章我們知道求解迷宮通路的方法,但是一個迷宮有時是不止一條出路,在這些出路中,我們如何找到最短的那一條,這就是我今天要說的迷宮最短路徑問題。 (此處使用的圖): 【先來分析有什麼解決方案:】 1、方法一:我們如果採用上章中遞迴的方式,將所走的路用2標記起來
用棧解決迷宮問題(輸出所有路徑和最短路徑)
#include<iostream> #include<cstdio> using namespace std; #define M 4 //行數 #define N 4 //列數 #define MaxSize 100 //棧最多元素個數 int m
1003 Emergency (25 分)(求最短路徑)
給出N個城市,m條無向邊。每個城市中都有一定數目的救援小組,所有邊的邊權已知。現在給出起點和終點,求從起點到終點的最短路徑條數及最短經上的救緩小組數目只和。如果有多條最短路徑,則輸出數目只和最大的 Dijkstra 做法 #include<bits/stdc++.h> using nam
利用graphviz來實現無向圖視覺化(求最短路徑)
1.首先下載graphviz,並安裝。 2.將輸入的邊儲存起來。 3.將最短路徑求出,並存儲每個頂點的前驅。 4.在程式中將建邊的程式碼寫入一個dot檔案中。 5.將dot檔案轉化為.png形式。 6.利用system函式開啟.png。 程式碼如下: #include &
Dijkstra--POJ 2502 Subway(求出所有路徑再求最短路徑)
題意: 你從家往學校趕,可以用步行和乘坐地鐵這兩種方式,步行速度為10km/h,乘坐地鐵的速度為40KM/h。輸入資料的第一行資料會給你起點和終點的x和y的座標。然後會給你數目不超過200的雙向地鐵線路的站點,你可以從一個站點乘坐地鐵到下一個站點,你可以在同一線
最少步數 (bfs最短路徑)
描述 這有一個迷宮,有0~8行和0~8列: 1,1,1,1,1,1,1,1,1 1,0,0,1,0,0,1,0,1 1,0,0,1,1,0,0,0,1 1,0,1,0,1,1,0,1,1 1,0,0,0,0,1,0,0,1 1,1,0,1,0,1,0,0