leetcode 529.掃雷遊戲(DFS)

leetcode 529.掃雷遊戲(DFS)

題目描述

在這裏插入圖片描述

樣例描述

在這裏插入圖片描述

算法分析

這個題仍是規矩比較多的,尤爲是一開始打算用C語言作(本人學習密碼編碼學,算法工程上都是用C實現,因此刻意練習用C寫算法)。一看到那個C語言提交的模板就傻了,那參數多的啊……果斷C++寫!算法

好了,廢話很少說!數組

提煉題目描述

給出click的位置,要求問你click以後的遊戲面板會變成啥子模樣~
若是你不當心點到了雷,那就顯示一個 ‘X’ ,遊戲天然結束(和掃雷同樣~)
不然就須要去處理不少東西了,你想一想看,本身玩掃雷的時候,是否是一點就空出來一大片,這就是根據這個算法去處理的。處理的規則是什麼呢??markdown

規則1 :

若是你點到的周圍有雷,那麼就不繼續了,只留下八個方向上雷的個數,告訴玩家。ide

規則2:

若是你點到的八個方向上一個雷也沒有,那就由 ‘E’ 變成 ‘B’ 。至關於告訴玩家,你點過了,這也是爲什麼你掃雷遊戲有時候一點空出一大片的緣由。就是由於這個位置周圍沒有雷,因此直接顯示成 ‘E’ !!性能

編碼實現

好了,規則其實也就這麼兩點啦,是本身太浮躁一開始沒看進去啦~學習

而後如何編碼實現呢?給出一個click的點,而後你能夠獲得click的行 r 和 列 c,若是這個位置就是雷,那麼直接表示成 ‘X’ ,本次 click 結束!不然進入dfs()!編碼

具體怎麼去 dfs 呢?首先初始化的面板只有 ‘M’ 和 ‘E’ ,因此可以進入 dfs() 就說明你當前是 ‘E’,因此須要先判斷它周圍有無雷,有的話,求出有多少,而後此處的位置改爲數字便可!改爲數字以後這個位置也不須要繼續下去了~不然就說明這個位置周圍沒有雷,就改爲 ‘B’,表明是個周圍沒有雷的,且已經點擊過的地方!!而後朝着八個方向去遞歸,而遞歸的出口如何處置呢?咱們能夠設置一個狀態記錄的數組,若是當前的點是已經處理過的,那就return,就行了!atom

具體解題代碼

class Solution {
public:
    int dir[8][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}};
    int vis[50][50] = {0};
    void dfs(int x, int y, vector<vector<char>>& board){
        if(vis[x][y])
            return ;
        vis[x][y] = 1;
        int cnt = 0;
        for(int i = 0;i < 8;++i){
            int dx = x + dir[i][0];
            int dy = y + dir[i][1];
            if(dx >= 0 && dx < (int)board.size() && dy >= 0 && dy < (int)board[0].size()){
                if('M' == board[dx][dy])
                    cnt++;
            }
        }
        if(cnt > 0){
            board[x][y] = cnt + '0';
        }
        else{
            board[x][y] = 'B';
            for(int i = 0;i < 8;++i){
                int dx = x + dir[i][0];
                int dy = y + dir[i][1];
                if(dx >= 0 && dx < (int)board.size() && dy >= 0 && dy < (int)board[0].size())
                    if(!vis[dx][dy])
                        dfs(dx, dy, board);
            }
        }
    }

    vector<vector<char>> updateBoard(vector<vector<char>>& board, vector<int>& click) {
        int r = click[0], c = click[1];
        if('M' == board[r][c])
            board[r][c] = 'X';
        else
            dfs(r, c, board);
        return board;
    }

};

提交的結果

在這裏插入圖片描述
這個性能很不理想啊,但願有提出更好的解決方案的同仁前輩,不吝賜教!spa

解答一個問題

有不少人會問,爲什麼樣例的正上方還有一個 ‘E’ 沒有被處理呢??
其實很簡單,由於從click的位置出發,在遇到這個 ‘E’ 以前,會遇到周圍有雷的位置,遇到這些位置的時候,就會中止遞歸處理了!因此沒法處理這個 ‘E’ ~
其實你去玩掃雷這個遊戲,也會發現,人家也就是這麼處理的!code

寫在後面

因爲本人能力有限,若是有寫錯或者有瑕疵的地方,還請各位不吝賜教!但願可以經過留言私信,獲得您的指教!

相關文章
相關標籤/搜索