leetcode 529.マインスイーパゲーム(DFS)

leetcode 529.マインスイーパゲーム(DFS)

タイトル説明

ここに画像の説明を挿入

サンプル概要

ここに画像の説明を挿入

アルゴリズムの分析

この質問には多くのルールがあり、特に最初にCでそれを行う予定がある場合(私は暗号を研究しており、アルゴリズムエンジニアリングはCで実装されているため、意図的にCでアルゴリズムの記述を練習します)。C言語によって提出されたテンプレートを見るとすぐに、私はばかげていて、非常に多くのパラメーターがありました... C ++で思い切って書いてください!

よし、これ以上はねないで!

トピックの説明を絞り込む

クリックの場所を指定し、クリックした後のゲームパネルの外観を尋ねます〜
誤って地雷をクリックした場合、「X」が表示され、ゲームは自然に終了します(マインスイーパと同じ
です)。それ以外の場合は対処する必要があります。マインスイーパを自分でプレイするとき、一度に広いエリアを空けるだけですか?これはこのアルゴリズムに従って処理されます。処理ルールは何ですか?

ルール1:

クリックしたポイントの周りに雷がある場合は、続行せず、8つの方向に雷の数を残して、プレーヤーに知らせてください。

ルール2:

クリックした8方向に雷がない場合、「E」から「B」に変わります。これは、プレイヤーにクリックしたことを伝えるのと同じです。そのため、マインスイーパゲームでは、多くのスペースが残されることがあります。この場所の周りには雷がないため、直接「E」と表示されます!

コーディングの実装

さて、ルールは実は2点だけです。私はあまりにもせっかちで、最初はそれを調べなかったからです〜

それをコード化する方法は?クリックポイントを与えると、クリックの行rと列cを得ることができます。この位置が雷の場合、それは直接「X」と表され、このクリックは終わりです!それ以外の場合は、dfs()を入力してください!

具体的にどのようにdfsに行くのですか?まず、初期化されたパネルには「M」と「E」しかありません。したがって、dfs()に入ることができるということは、現在「E」であることを意味します。そのため、雷が発生しているかどうかを判断する必要があります。の位置を番号に変更してください!数値に変更した後、この位置はもう継続する必要はありません〜それ以外の場合は、この位置の周りに雷がないことを意味するので、それを「B」に変更します。これは、周りに雷がなく、クリックされたことを意味します!次に、8つの方向に再帰します。再帰的な出口に対処する方法は?ステータスレコードの配列を設定できます。現在のポイントが処理されている場合は、戻ります。

特定の問題解決コード

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;
    }

};

提出された結果

ここに画像の説明を挿入
このパフォーマンスは非常に満足できるものではありません。より良い解決策を考え出す上級の同僚がいることを願っています。

質問に答えます

多くの人が尋ねるでしょう、なぜ処理されていないサンプルのすぐ上に「E」があるのですか?
クリックの位置から始めて、この「E」に遭遇する前に、雷が発生している場所に遭遇し、これらの場所に遭遇すると、再帰的な処理が停止するため、実際には非常に単純です。だから、これに対処することはできません 'E'〜
実際、マインスイーパのゲームをプレイすると、これが人々の対処法だということがわかります!

後ろに書く

私の能力は限られているため、間違いや欠陥がある場合は、遠慮なく教えてください!プライベートメッセージを残してアドバイスをいただければ幸いです!

おすすめ

転載: blog.csdn.net/qq_44274276/article/details/108134879