1. 程式人生 > 其它 >C++-字元迷宮 解題思路

C++-字元迷宮 解題思路

【Horn Studio】程式設計專欄: 抓住那頭牛 解題思路

題目

題目描述

   給你一個n行m列的二維迷宮。 'S' 表示起點, 'T' 表示終點, '#'表示牆壁,'.' 表示平地。你需要從 'S' 出發走到 'T',每次只能上下左右走動,並且不能走出地圖的範圍以及不能走到牆壁上。請你計算出走到終點需要走的最少步數。

輸入

第一行輸入n,m表示迷宮大小。(100以內)

接下來輸入n行字串表示迷宮,每個字串長度為m。(地圖保證有且僅有一個終點,一個起始點)

輸出

輸出走到終點的最少步數,如果不能走到終點輸出-1,佔一行。

樣例輸入 

2 3
S.#
..T

樣例輸出 

3

提示

樣例輸入2
3 3
S.#
.#.
.#T
樣例輸出2
-1

來源

思路

這道題同樣是一道經典的BFS,對於bfs的描述,請詳見:C++-BFS 廣搜的含義 - 馮子坤 - 部落格園 (cnblogs.com)

這道題如果使用char純字元計算,不僅空間複雜度大,還隨時可能TLE,因此,我們需要在輸入時把他們轉換一下……就像這樣。

 1 for (int i = 1; i <= n; i++)
 2         for (int j = 1; j <= m; j++) {
 3             char ip1;
 4             cin >> ip1;
5 if (ip1 == 'S') { 6 bx = i; 7 by = j; 8 } else if (ip1 == '.') 9 a[i][j] = 1; 10 else if (ip1 == 'T') 11 a[i][j] = 2; 12 else 13 a[i][j] = 0; 14 }

這樣轉換成數字,後續寫程式也要容易得多;

另外我們需要定義一個結構體,高度整合!

1 struct point {
2     int x;
3     int y;
4     point(int xx, int yy)
5     {
6         x = xx;
7         y = yy;
8     }
9 };

至於BFS程式碼嗎……這裡就是用虛擬碼來給大家理解吧:

void bfs(int sx, int sy) {  // (sx, sy) 為搜尋的起點

    queue<point> q;

    q.push(point(sx, sy));  // 將起始點放入佇列中

    用vis陣列標記(x, y)已經被訪問過;

    while(佇列非空) {

        取出佇列元素(x, y);

        for (列舉(x, y)能到達的所有格子(tx, ty)) {

            if (點(tx, ty)合法,可以搜尋) {

                標記(tx, ty)已經被訪問過;

                記錄走到(tx, ty)的步數 = 走到(x, y)的步數 + 1;

                q.push(point(tx, ty))

            }

        }

    }

    return;

}

 

接下來就是把它們轉換成真正程式碼了!;

程式碼

#include <bits/stdc++.h>
using namespace std;
int a[105][105], mark[105][105], b[105][105];
int mn = 0;
 
int chx[4] = {1, 0, -1, 0};
 
int chy[4] = {0, 1, 0, -1};
 
struct point {
    int x;
    int y;
    point(int xx, int yy)
    {
        x = xx;
        y = yy;
    }
};
 
int bfs(int i, int j)
{
    queue<point>q;
    q.push(point(i, j));
    mark[i][j] = 1;
    while (!q.empty()) {
        i = q.front().x;
        j = q.front().y;
        q.pop();
        for (int k = 0; k < 4; k++) {
            int tx = i + chx[k];
            int ty = j + chy[k];
            if (!mark[tx][ty] && a[tx][ty]) {
                mn = b[i][j] + 1;
                b[tx][ty] = mn;
                mark[tx][ty] = 1;
                if (a[tx][ty] == 2)
                    return 1;
                else
                    q.push(point(tx, ty));
            }
        }
    }
    return 0;
}
 
int main()
{
    int n, m;
    int bx, by;
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++) {
            char ip1;
            cin >> ip1;
            if (ip1 == 'S') {
                bx = i;
                by = j;
            } else if (ip1 == '.')
                a[i][j] = 1;
            else if (ip1 == 'T')
                a[i][j] = 2;
            else
                a[i][j] = 0;
        }
    if (bfs(bx, by))
        cout << mn;
    else
        cout << -1;
    return 0;
}

彩蛋

 

使用此部落格請標明出處!否則一律視為盜版!做人有底線!