AcWing走迷宮-最短路問題-BFS求解

題目描述

給定一個 n * m 的二維整數數組,用來表示一個迷宮,數組中只包含 01,其中 0 表示可以走的路,1 表示不可通過的墻壁。

最初,有一個人位于左上角 (1, 1) 處,已知該人每次可以向上、下、左、右任意一個方向移動一個位置。

請問,該人從左上角移動至右下角 (n, m) 處,至少需要移動多少次。

數據保證 (1, 1) 處和 (n, m) 處的數字為 0,且一定至少存在一條通路。


輸入格式

  • 第一行包含兩個整數 nm
  • 接下來 n 行,每行包含 m 個整數(01),表示完整的二維數組迷宮。

輸出格式

輸出一個整數,表示從左上角移動至右下角的最少移動次數。


數據范圍

  • 1 ≤ n, m ≤ 100

輸入輸出樣例

樣例輸入 1

復制

5 5
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
樣例輸出 1

復制

8

實現思路:
我么使用一個隊列存儲可能的路徑(x,y),每次拿隊頭的元素判斷下一步可以走的位置,如果可以走且之前沒有走過,那么將該坐標放入隊尾。當隊列不為空就說明有位置可以走,就一直走下去,當所有位置都走完時,右下角的距離就是最短路徑。

這個隊列中的元素是個坐標,所以可以用pair類型存儲,同時隊列的實現可以通過數組+頭尾指針實現:隊頭用hh標記,隊尾用tt標記,開始都初始化為0,拿出隊頭元素t:PII t = q[hh++](先拿出來隊頭hh再++),當對頭的下一個位置滿足條件時,將其放入隊尾q[++tt]={x,y};(隊尾先++再賦值)

代碼實現

#include<iostream>
using namespace std;
const int N = 110;
typedef pair<int, int> PII;
//g用于存儲圖,d用于記錄每個坐標到初始位置的最短距離
int g[N][N], d[N][N];
int n, m;
PII q[N * N];  //q用于存儲每個符合條件的坐標,(即路徑)int bfs()
{//頭尾指針,用于指向模擬隊列int head = 0, tail = 0;q[0] = { 0,0 };  //首先從下標0,0位置開始memset(d, -1, sizeof d); //先將d初始話為-1d[0][0] = 0;  //0,0坐標到0,0的距離當然是0啦/** dx和dy用于記錄上下左右四個方向* 如dx[0]dy[0]就表示x-1,y,即向上以一格*/int dx[4] = { -1,0,1,0 }, dy[4] = { 0,1,0,-1 }; while (head <= tail){//先獲取隊列頭頂元素,再head++將其出隊auto t = q[head++];for (int i = 0; i < 4; i++){//表示枚舉該坐標的4個方向int x = t.first + dx[i];int y = t.second + dy[i];//如果這個位置為0(可以走),x<n,y<m(沒出界),d[x][y]==-1(沒被走過)if (g[x][y] == 0 && x < n && y < m && d[x][y] == -1){//該坐標下的最短路就是上一個坐標的長度+1d[x][y] = d[t.first][t.second] + 1;q[++tail] = { x,y }; //將其入隊}}}return d[n - 1][m - 1];
}
int main()
{cin >> n >> m;for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)cin >> g[i][j];cout << bfs() << endl;return 0;
}

代碼思路總結

通過 廣度優先搜索(BFS) 解決了迷宮最短路徑問題。以下是代碼的詳細思路總結:


1. 問題分析

  • 給定一個 n * m 的二維數組表示迷宮,0 表示通路,1 表示墻壁。
  • 從起點 (0, 0) 出發,每次可以向上、下、左、右移動一個位置,求到達終點 (n-1, m-1) 的最短路徑長度。

2. 核心思路

  • 使用 BFS 逐層遍歷迷宮,確保第一次到達終點時的路徑是最短的。
  • 使用一個隊列來存儲待訪問的節點,并通過一個二維數組 d 記錄每個節點到起點的最短距離。

3. 代碼實現步驟

(1) 初始化
  • 定義二維數組 g 存儲迷宮,d 存儲每個節點到起點的最短距離。
  • 使用 pair<int, int> 表示坐標,并用數組 q 模擬隊列。
  • 初始化隊列 q,將起點 (0, 0) 加入隊列,并設置 d[0][0] = 0
(2) BFS 遍歷
  • 使用 while 循環不斷從隊列中取出節點,直到隊列為空。
  • 對于每個節點,枚舉其四個方向(上、下、左、右):
    • 計算新坐標 (x, y)
    • 檢查新坐標是否合法(未越界、是通路 0、未被訪問過 d[x][y] == -1)。
    • 如果合法,更新新坐標的最短距離,并將其加入隊列。
(3) 終止條件
  • 當遍歷到終點 (n-1, m-1) 時,d[n-1][m-1] 即為最短路徑長度。

4. 代碼細節解析

(1) 隊列的實現
  • 使用數組 q 模擬隊列,headtail 分別表示隊頭和隊尾指針。
  • 入隊操作:q[++tail] = {x, y}
  • 出隊操作:auto t = q[head++]
(2) 方向數組
  • 使用 dxdy 數組表示四個方向的偏移量:

    cpp

    復制

    int dx[4] = {-1, 0, 1, 0}; // 上、右、下、左
    int dy[4] = {0, 1, 0, -1};
    
  • 通過循環枚舉四個方向,簡化代碼。

(3) 距離數組 d
  • d[i][j] 表示從起點 (0, 0)(i, j) 的最短距離。
  • 初始時,d 數組全部初始化為 -1,表示未訪問。
  • 每次更新新坐標的距離:d[x][y] = d[t.first][t.second] + 1
(4) 邊界檢查
  • 檢查新坐標 (x, y) 是否在迷宮范圍內:

    cpp

    復制

    x < n && y < m
    
  • 檢查新坐標是否是通路:

    cpp

    復制

    g[x][y] == 0
    
  • 檢查新坐標是否未被訪問過:

    cpp

    復制

    d[x][y] == -1
    

5. 復雜度分析

(1) 時間復雜度
  • 每個節點最多被訪問一次,因此時間復雜度為 O(n * m)
(2) 空間復雜度
  • 使用了一個隊列和一個距離數組,空間復雜度為 O(n * m)

6. 示例運行

輸入

復制

5 5
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
輸出

復制

8

7. 總結

  • 通過 BFS 實現了迷宮最短路徑的求解,利用了隊列的先進先出特性,確保第一次到達終點時的路徑是最短的。

算法刷題日記

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/70503.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/70503.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/70503.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

go 錯誤處理 error

普通錯誤處理 // 包路徑 package mainimport ("errors""fmt" )func sqrt(f1, f2 float64) (float64, error) {if f2 < 0 {return 0, errors.New("error: f2 < 0")}return f1 / f2, nil }func sqrt1(f1, f2 float64) {if re, err : sqrt(f…

MCU Bootloader具備什么條件才能跳轉到APP程序

在MCU系統中&#xff0c;BootLoader&#xff08;Boot&#xff09;跳轉到應用程序&#xff08;APP&#xff09;的條件通常由硬件和軟件協同控制&#xff0c;核心邏輯是確保APP的完整性和合法性。以下是關鍵條件及流程&#xff1a; 1. 硬件啟動模式選擇 BOOT引腳電平&#xff1a…

LeeCode題庫第二十八題

28.找出字符串第一個匹配項的下標 項目場景&#xff1a; 給你兩個字符串 haystack 和 needle &#xff0c;請你在 haystack 字符串中找出 needle 字符串的第一個匹配項的下標&#xff08;下標從 0 開始&#xff09;。如果 needle 不是 haystack 的一部分&#xff0c;則返回 …

深入解析BFS算法:C++實現無權圖最短路徑的高效解決方案

在無權圖中&#xff0c;廣度優先搜索&#xff08;BFS&#xff09;是解決最短路徑問題的高效算法。接下來博主從專業角度深入探討其實現細節&#xff0c;并給出C代碼示例&#xff1a; 目錄 一、核心原理 二、算法步驟 三、C實現關鍵點 1. 數據結構 2. 邊界檢查 3. 路徑回溯…

Plant Simulation培訓教程-雙深堆垛機立庫仿真模塊

原創 知行 天理智能科技 2025年01月03日 17:02 浙江 又到年終盤點的時候了&#xff0c;在這里我把之前錄制的Plant Simulation培訓教程-雙深堆垛機立庫仿真模塊分享出來&#xff0c;有需要的可以直接聯系我。 雙深堆垛機立庫仿真模塊基于單深模塊開發&#xff0c;適用于雙深堆…

文本和語音互轉

目錄 1. 下載依賴ddl 2. 引入Pom依賴 3. java代碼 二. 語音轉文本 1. 下載中文語音轉文本的模型 2. 引入pom依賴 3. java代碼 4. 運行效果 1. 下載依賴ddl 文字轉語音文件需要使用jacob的dll文件放在jdk安裝目錄下的bin文件夾下 點擊官網下載錄或者通過csdn下載 2. …

DeepSeek破局啟示錄:一場算法優化對算力霸權的降維打擊

導言 2024年,中國AI大模型賽道殺出一匹黑馬——深度求索(DeepSeek)。從數學推理能力超越GPT-4,到API價格僅為Claude 3.5的1/53,再到開源生態的快速擴張,DeepSeek的崛起不僅打破了“算力霸權”的固有認知,更揭示了AI行業底層邏輯的深刻變革。這場技術革命背后,隱藏著技術…

Python大數據可視化:基于python大數據的電腦硬件推薦系統_flask+Hadoop+spider

開發語言&#xff1a;Python框架&#xff1a;flaskPython版本&#xff1a;python3.7.7數據庫&#xff1a;mysql 5.7數據庫工具&#xff1a;Navicat11開發軟件&#xff1a;PyCharm 系統展示 管理員登錄 管理員功能界面 價格區間界面 用戶信息界面 品牌管理 筆記本管理 電腦主機…

阿里云虛機的遠程桌面登錄提示帳戶被鎖定了

提示由于安全原因&#xff0c;帳戶被鎖定。 阿里云虛機ECS的遠程桌面登錄提示帳戶被鎖定了&#xff0c;只能登錄阿里云處理 阿里云-計算&#xff0c;為了無法計算的價值 需選擇通過VNC連接 然后計算機管理&#xff0c;解除帳戶鎖定即可。

Grok 使用指南

文章來源&#xff1a;Grok 漫游指南 | xAI Docs 歡迎&#xff01;在本指南中&#xff0c;我們將引導您了解使用 xAI API 的基礎知識。 #第 1 步&#xff1a;創建 xAI 帳戶 您需要一個 xAI 帳戶才能訪問 xAI API。在此處注冊帳戶。 創建賬戶后&#xff0c;您需要為其加載積分…

Node.js高頻面試題精選及參考答案

目錄 什么是 Node.js?它的主要特點有哪些? Node.js 的事件驅動和非阻塞 I/O 模型是如何工作的? 為什么 Node.js 適合處理高并發場景? Node.js 與傳統后端語言(如 Java、Python)相比,有哪些優勢和劣勢? 簡述 Node.js 的運行原理,包括 V8 引擎的作用。 什么是 Nod…

Servlet概述(Ⅰ)

目錄 一、Servlet概述 演示 創建JavaWeb項目&#xff08;2017版本為例&#xff09; 1. 打開 IntelliJ IDEA 2. 選擇項目類型 3. 配置框架 二、Servlet初識(熟練) 1.servlet說明 2.Servlet 接口方法 3.創建Servlet 4.JavaWeb請求響應流程 ?編輯 ?編輯 5.servlet…

Windows 小記 18 —— 子窗口繼承父窗口的樣式

子窗口會繼承父窗口或者所有者窗口的一些樣式。 當我們使用 CreateWindowExW 創建窗口后&#xff0c;指定其 HwndParent 參數時&#xff0c;或者通過 SetWindowLongPtr(vd->Hwnd, GWLP_HWNDPARENT, (LONG_PTR)vd->HwndParent); 指定所有者窗口時&#xff0c;子窗口將從父…

19、《Springboot+MongoDB整合:玩轉文檔型數據庫》

SpringbootMongoDB整合&#xff1a;玩轉文檔型數據庫 摘要&#xff1a;本文全面講解Spring Boot與MongoDB的整合實踐&#xff0c;涵蓋環境搭建、CRUD操作、聚合查詢、事務管理、性能優化等核心內容。通過15個典型代碼示例&#xff0c;演示如何高效操作文檔數據庫&#xff0c;深…

跳躍游戲II(力扣45)

這道題在跳躍游戲(力扣55)-CSDN博客 的基礎上需要找到最小的跳躍次數。那么我們需要用一個變量來統計跳躍次數&#xff0c;而難點就在于何時讓該變量的值增加。這一點我寫在注釋中&#xff0c;大家結合我的代碼會更好理解。其他部分跟跳躍游戲(力扣55)-CSDN博客 幾乎相同&#…

Linux基礎開發工具的使用(apt、vim、gcc、g++、gdb、make、makefile)

Linux軟件包管理器–apt Linux安裝軟件的方式 在Linux下安裝軟件的方法有以下三種&#xff1a; 下載到程序的源代碼&#xff0c;自己編譯出可執行程序獲取deb安裝包、然后使用dpkg命令安裝。&#xff08;不解決依賴關系&#xff09;通過apt進行安裝軟件。 小知識點&#xf…

C/C++ | 每日一練 (2)

&#x1f4a2;歡迎來到張胤塵的技術站 &#x1f4a5;技術如江河&#xff0c;匯聚眾志成。代碼似星辰&#xff0c;照亮行征程。開源精神長&#xff0c;傳承永不忘。攜手共前行&#xff0c;未來更輝煌&#x1f4a5; 文章目錄 C/C | 每日一練 (2)題目參考答案封裝繼承多態虛函數底…

【前端框架】vue2和vue3的區別詳細介紹

Vue 3 作為 Vue 2 的迭代版本&#xff0c;在性能、語法、架構設計等多個維度均有顯著的變革與優化。以下詳細剖析二者的區別&#xff1a; 響應式系統 Vue 2 實現原理&#xff1a;基于 Object.defineProperty() 方法實現響應式。當一個 Vue 實例創建時&#xff0c;Vue 會遍歷…

基于Spring Boot的農事管理系統設計與實現(LW+源碼+講解)

專注于大學生項目實戰開發,講解,畢業答疑輔導&#xff0c;歡迎高校老師/同行前輩交流合作?。 技術范圍&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬蟲、數據可視化、安卓app、大數據、物聯網、機器學習等設計與開發。 主要內容&#xff1a;…

【RISCV 常見匯編指令學習 1.2 -- CSRW | CSRR | XORI | ANDI | DRET | J | JR】

文章目錄 Overview1. CSRW 與 CSRR2. SW 與 lw3. XORI 與 ANDI4. J 與 JR5. ret 與 dret6. 總結&#x1f310; Sources Overview 在 RISCV 匯編中&#xff0c;不同類型的指令用于完成控制寄存器操作、內存存取、位操作、跳轉以及返回等功能。下面將逐對詳細介紹這些指令&#…