華爲機試 是否存在路徑(深度優先遍歷、回朔法、遞歸)

題目:輸入一個矩陣以及其行列值,矩陣中‘-’表示可以移動的座標,‘#’表示障礙物不可以通過,‘B’表示起點,‘H’表示終點。在矩陣中可以上下左右移動,不可以斜線移動,求問是否存在從起點B到終點H的路徑。
例如輸入:

3 3
B - -
# # -
- H -

則應該輸出YES

題目分析:題目是圖論遍歷問題,可以採用深度優先遍歷的方法進行路徑查找。採用回朔法、遞歸的思路解決問題。代碼如下。

#include <iostream>
#include <vector>

using namespace std;

class Pos
{
public:
    void set (int i, int j)
    {
        x = i, y = j;
    }
    int getx()
    {
        return x;
    }
    int gety()
    {
        return y;
    }
private:
    int x;
    int y;
};

bool haspath(vector<char> & cv, vector<bool> & bv,int rows, int columns, int row, int column)
{

    bool result = false;
    if (row >= 0 && row < rows&&column >= 0 && column < columns&&!bv[row*columns + column])
    {
        if (cv[row*columns + column] == 'H')
            return true;
        if (cv[row*columns + column] == '#')
            return false;
            bv[row*columns + column] = true;
            result = haspath(cv, bv, rows, columns, row - 1, column)
                || haspath(cv, bv, rows, columns, row, column + 1)
                || haspath(cv, bv, rows, columns, row + 1, column)
                || haspath(cv, bv, rows, columns, row, column - 1);

            //觀察中間結果用打印數據
        /*  for (int i = 0; i < rows; ++i)
            {
                for (int j = 0; j < columns; ++j)
                    cout << bv[i*columns + j] << " ";
                cout << endl;
            }
            cout << endl;*/

            if (!result)
                bv[row*columns + column] = false;
    }
    return result;
}

int main()
{
    int rows, columns;
    cin >> rows >> columns;
    Pos Begin;
    vector<char> cvect;
    vector<bool> bvect;
    char temp;
    for (int i = 0; i < rows; ++i)
        for (int j = 0; j < columns; ++j)
        {
            cin >> temp;
            cvect.push_back(temp);
            if (temp == 'B')
                Begin.set(i, j);
            bvect.push_back(false);
        }
    bool possible;
    possible=haspath(cvect,bvect,rows,columns,Begin.getx(),Begin.gety());
    if(possible)
        cout << "YES"<<endl;
    else
        cout << "NO" << endl;
}

測試結果如下圖:

這裏寫圖片描述

代碼中註釋的部分打印了記錄路徑的容器,如取消註釋打印結果如下:
0 1 1 0 1 1
0 1 0 1 1 0
1 1 0 1 0 0
1 0 1 1 0 0
1 1 1 0 0 0

0 1 1 0 1 0
0 1 0 1 1 0
1 1 0 1 0 0
1 0 1 1 0 0
1 1 1 0 0 0

0 1 1 0 0 0
0 1 0 1 1 0
1 1 0 1 0 0
1 0 1 1 0 0
1 1 1 0 0 0

0 1 1 0 0 0
0 1 0 1 0 0
1 1 0 1 0 0
1 0 1 1 0 0
1 1 1 0 0 0

0 1 1 0 0 0
0 1 0 0 0 0
1 1 0 1 0 0
1 0 1 1 0 0
1 1 1 0 0 0

0 1 1 0 0 0
0 1 0 0 0 0
1 1 0 0 0 1
1 0 1 1 1 1
1 1 1 0 0 0

0 1 1 0 0 0
0 1 0 0 0 0
1 1 0 0 0 0
1 0 1 1 1 1
1 1 1 0 1 1

0 1 1 0 0 0
0 1 0 0 0 0
1 1 0 0 0 0
1 0 1 1 1 1
1 1 1 0 1 1

0 1 1 0 0 0
0 1 0 0 0 0
1 1 0 0 0 0
1 0 1 1 1 1
1 1 1 0 1 1

0 1 1 0 0 0
0 1 0 0 0 0
1 1 0 0 0 0
1 0 1 1 1 1
1 1 1 0 1 1

0 1 1 0 0 0
0 1 0 0 0 0
1 1 0 0 0 0
1 0 1 1 1 1
1 1 1 0 1 1

0 1 1 0 0 0
0 1 0 0 0 0
1 1 0 0 0 0
1 0 1 1 1 1
1 1 1 0 1 1

0 1 1 0 0 0
0 1 0 0 0 0
1 1 0 0 0 0
1 0 1 1 1 1
1 1 1 0 1 1

0 1 1 0 0 0
0 1 0 0 0 0
1 1 0 0 0 0
1 0 1 1 1 1
1 1 1 0 1 1

0 1 1 0 0 0
0 1 0 0 0 0
1 1 0 0 0 0
1 0 1 1 1 1
1 1 1 0 1 1

0 1 1 0 0 0
0 1 0 0 0 0
1 1 0 0 0 0
1 0 1 1 1 1
1 1 1 0 1 1

0 1 1 0 0 0
0 1 0 0 0 0
1 1 0 0 0 0
1 0 1 1 1 1
1 1 1 0 1 1

0 1 1 0 0 0
0 1 0 0 0 0
1 1 0 0 0 0
1 0 1 1 1 1
1 1 1 0 1 1

0 1 1 0 0 0
0 1 0 0 0 0
1 1 0 0 0 0
1 0 1 1 1 1
1 1 1 0 1 1

0 1 1 0 0 0
0 1 0 0 0 0
1 1 0 0 0 0
1 0 1 1 1 1
1 1 1 0 1 1

0 1 1 0 0 0
0 1 0 0 0 0
1 1 0 0 0 0
1 0 1 1 1 1
1 1 1 0 1 1
可以看出,雖然解決了路徑是否存在的問題,但這並不是最短路徑。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章