回溯法求迷宮問題

tegou發表於2024-10-12

回溯法求迷宮問題

求解思路

1.初始化迷宮:定義一個二維陣列表示迷宮,並設定起點和終點。
2.定義回溯函式:透過遞迴方式探索每一條路徑,更新當前路徑和步數。
3.剪枝策略:在每一步判斷是否需要繼續深入(如步數是否已超過最短路徑)。
4.輸出結果:記錄並輸出最短路徑的長度。

回溯法的基本思想

回溯法透過構建搜尋樹來逐步嘗試所有可能的路徑。對於迷宮問題,主要步驟如下:

1.從起點開始,嘗試向四個方向(下、左、右、上)移動。
2.如果移動到的新位置是可通行的,則繼續進行移動。
3.在每次移動後,檢查是否到達終點。
4.若當前位置不再有可移動路徑,則回退到上一步,嘗試其他方向(即“回溯”)。
5.使用剪枝策略避免不必要的計算,例如:
6.標記已訪問的節點,防止重複訪問。
7.檢查當前路徑長度是否已經超過已知的最短路徑長度。

程式碼如下

#include<bits/stdc++.h>
using namespace std;

int minSteps = INT_MAX;
int sx,sy,ex,ey;
int n,m;
const int dx[] = {1, 0, -1, 0};
const int dy[] = {0, -1, 0, 1};
int visited[110][110];
char mig[110][110];//迷宮 

void backtrack(int x, int y, int steps) {
    if (x == ex && y == ey) {
        if (steps < minSteps) {
            minSteps = steps;
        }
        return;
    }
    if (steps >= minSteps) return;
    for (int i = 0; i < 4; ++i) {
        int newX = x + dx[i];
        int newY = y + dy[i];
        if(mig[newX][newY] == '#'){
            visited[newX][newY] = 1;
        }
        if (newX >= 1 && newX <= n && newY >= 1 && newY <= m && mig[newX][newY] == '.') {
            visited[newX][newY] = 1;
            backtrack(newX, newY,  steps + 1);
            visited[newX][newY] = 0;
        }
    }
}

int main() {
    cin>>n>>m;
    for(int i = 1; i <= n; i++){
        scanf("%s", mig[i]+1);
    }
    cin>>sx>>sy>>ex>>ey;
    visited[sx][sy] = 1;
    backtrack(sx, sy, 0);
    if (minSteps < INT_MAX) {
        cout << "最小步數: " << minSteps << endl;
    } else {
        cout << "無解" << endl;
    }
    return 0;
}

相關文章