<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
迷宮由 n 行 m 列的單元格組成,每個單元格要麼是空地,要麼是障礙物。其中1表示空地,可以走通,2表示障礙物。給定起點座標startx,starty以及終點座標endx,endy。現請你找到一條從起點到終點的最短路徑長度。
第一行包含兩個整數n,m(1<=n,m<=1000)。接下來 n 行,每行包含m個整數(值1或2),用於表示這個二維迷宮。接下來一行包含四個整數startx,starty,endx,endy,分別表示起點座標和終點座標。
如果可以從給定的起點到終點,輸出最短路徑長度,否則輸出NO。
輸入
5 4
1 1 2 1
1 1 1 1
1 1 2 1
1 2 1 1
1 1 1 2
輸出
7
這道題屬於一道較為經典的BFS圖的廣度優先搜尋演演算法例題。類似於一個分層搜尋的過程,廣度優先搜尋需要使用一個佇列以保持存取過的結點的順序,以便按這個順序存取這些結點的鄰接結點。即從給定的起點開始向四周擴散,判斷是否能夠到達終點,如果不能,就繼續BFS廣搜,直到能夠到達終點或者將所有結點遍歷完一遍。在搜尋前定義一個flag變數用來標記是否到達終點。
1)存取初始結點 p 並標記結點 p 為已存取。
2)結點 p 入佇列
3)當佇列非空時,繼續執行,否則演演算法結束。
4)出佇列取得隊頭結點 first
5)查詢結點 first 的第一個方向的鄰接結點 newp 。
6)若結點 first 的鄰接結點 newp 不存在,則轉到步驟3:否則迴圈執行以下三個步驟:
import java.util.LinkedList; import java.util.Scanner; public class Main { //n*m的地圖,(startx,starty)起點座標,(endx,endy)終點座標 static int n, m, startx, starty, endx, endy; static int[][] map;//地圖 static boolean[][] vistied;//標記當前點是否已經走過 static int[][] step = { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } }; /* * 上下左右移動遍歷搜尋 1 ,0 表示 x + 1 ,y + 0 向右移動,其他同理 如果為八向連通 則加上, { 1, 1 }, { 1, -1 }, { * -1, 1 }, { -1, -1 } 代表斜向移動 */ public static void main(String[] args) { Scanner sc = new Scanner(System.in); n = sc.nextInt(); m = sc.nextInt(); map = new int[n + 2][m + 2];//+2是為了防止點在邊界時,四方向移動造成下標出現-1越界。 vistied = new boolean[n + 2][m + 2]; // 錄入資料圖 下標(1~n)*(1~m) for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { map[i][j] = sc.nextInt(); } } //錄入起點和終點座標 startx = sc.nextInt(); starty = sc.nextInt(); endx = sc.nextInt(); endy = sc.nextInt(); bfs(startx, starty);//BFS廣搜 } private static void bfs(int x, int y) { point p = new point(x, y, 0);//初始化point類封裝x,y座標以及step步數 LinkedList<point> queue = new LinkedList<point>();//需要用到的佇列 queue.add(p);//將當前點入佇列 vistied[x][y] = true;//標記成已存取 boolean flag = false;//是否達到終點標記 //只要佇列不為空,就說明還有路可走 while (!queue.isEmpty()) { point first = queue.getFirst();//取出佇列的第一個點 if (first.x == endx && first.y == endy) {//判斷當前點是否與終點座標重合 System.out.println(first.step);//列印需要走的步數 flag = true;//標記已經到達終點 break;//結束BFS } //未到達終點則進行上下左右四個方向移動 for (int i = 0; i < 4; i++) { //橫縱座標變換實現位置移動 int newx = first.x + step[i][0]; int newy = first.y + step[i][1]; int newstep = first.step + 1;//每一動一次步數要+1 //判斷移動後的新位置可以走,並且沒走過 if (map[newx][newy] == 1 && vistied[newx][newy] == false) { point newp = new point(newx, newy, newstep);//封裝資料 queue.add(newp);//入佇列 vistied[newx][newy] = true;//標記已經走過 } } queue.removeFirst();//四個方向判斷完成後,要將隊首元素出列 } if (!flag)//如果無法到達終點提示 System.out.println("NO"); } } //定義一個位置點的class,方便封裝資料入佇列 class point { int x; int y; int step;//從起點走到當前點需要走的步數 public point(int x, int y, int step) { this.x = x; this.y = y; this.step = step; } }
將隊首結點可拓展的點入隊,如果沒有可拓展的點,將隊首結點出隊。重複以上步驟,直到到達目標位置或者佇列為空。
bfs先找到的一定是最短的。但是如果是加權邊的話這樣就會出問題了,bfs傳回的是經過 邊數 最少的解,但是因為加權了,這個解到根節點的 距離 不一定最短。 比如1000+1000是隻有兩段,1+1+1+1有4段,由於bfs返回的經過邊數最少的解,這裡會返回總長度2000的那個解,顯然不是距離最短的路徑 。BFS 運用到了佇列。
到此這篇關於Java資料結構BFS廣搜法解決迷宮問題的文章就介紹到這了,更多相關Java 迷宮問題內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45