zoukankan      html  css  js  c++  java
  • 529. Minesweeper

    问题:

    扫雷问题:给定一个扫雷地图,

    包含:

    • M:埋雷cell
    • E:空区cell
    • X:已被挑出的雷cell
    • 1~8:已被扫过的空区cell,该cell四周的埋雷数。

    给出扫雷点击坐标click

    求,这次click之后的扫雷地图的状态。

    变化规则:

    • M:变为X,扫到雷,游戏结束。
    • E:四周无雷:变为B,再递归扫除四周cell。
    • E:四周有雷:变为四周的埋雷数。1~8。
    Example 1:
    Input: 
    [['E', 'E', 'E', 'E', 'E'],
     ['E', 'E', 'M', 'E', 'E'],
     ['E', 'E', 'E', 'E', 'E'],
     ['E', 'E', 'E', 'E', 'E']]
    Click : [3,0]
    Output: 
    [['B', '1', 'E', '1', 'B'],
     ['B', '1', 'M', '1', 'B'],
     ['B', '1', '1', '1', 'B'],
     ['B', 'B', 'B', 'B', 'B']]
    
    Example 2:
    Input: 
    [['B', '1', 'E', '1', 'B'],
     ['B', '1', 'M', '1', 'B'],
     ['B', '1', '1', '1', 'B'],
     ['B', 'B', 'B', 'B', 'B']]
    Click : [1,2]
    Output: 
    [['B', '1', 'E', '1', 'B'],
     ['B', '1', 'X', '1', 'B'],
     ['B', '1', '1', '1', 'B'],
     ['B', 'B', 'B', 'B', 'B']]
    
    Note:
    The range of the input matrix's height and width is [1,50].
    The click position will only be an unrevealed square ('M' or 'E'), which also means the input board contains at least one clickable square.
    The input board won't be a stage when game is over (some mines have been revealed).
    For simplicity, not mentioned rules should be ignored in this problem. For example, you don't need to reveal all the unrevealed mines when the game is over, consider any cases that you will win the game or flag any squares.
    

      

    Example 1:

    Example 2:

     解法:BFS

    queue中:从click的cell开始,存入坐标。

    • 入队条件:当前cell为E,且四周埋雷数count==0。
      • 则将该cell的四周cell入队,

    ♻️ 优化:为了防止重复入队相同的cell,则在第一次入队时,将该cell设为B。

    以后只有cell为E的时候,才入队。

    但是当前cell为B的时候,有可能其四周埋雷,需要更新为埋雷数量1~8。

    • 终止入队:(当前节点跳过,去处理queue中其他节点)
      • cell为M
      • or cell四周埋雷数>0。

    代码参考:

     1 class Solution {
     2 public:
     3     vector<vector<int>> dir = {{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};
     4     int n,m;
     5     int countM(int i, int j, vector<vector<char>>& board){
     6         int x = 0, y = 0;
     7         int count = 0;
     8         for(auto d:dir) {
     9             x=i+d[0], y=j+d[1];
    10             if(x<0 || y<0 || x>=n || y>=m) continue;
    11             if(board[x][y]=='M' || board[x][y]=='X')count++;
    12         }
    13         return count;
    14     }
    15     vector<vector<char>> updateBoard(vector<vector<char>>& board, vector<int>& click) {
    16         n = board.size();
    17         m = board[0].size();
    18         if(click[0]<0 || click[1]<0 || click[0]>=n || click[1]>=m) return board;
    19         /*vector<vector<int>> markboard(n, vector<int>(m,0));
    20         for(int i=0; i<n; i++) {
    21             for(int j=0; j<m; j++) {
    22                 if(board[i][j]=='M') markM(i,j,markboard, board);
    23             }
    24         }
    25         for(int i=0; i<n; i++) {
    26             for(int j=0; j<m; j++) {
    27                 printf("%d ", markboard[i][j]);
    28             }
    29             printf("
    ");
    30         }*/
    31         queue<pair<int, int>> q;
    32         q.push({click[0],click[1]});
    33         int cur_x, cur_y, x, y;
    34         while(!q.empty()) {
    35             int sz = q.size();
    36             for(int i=0; i<sz; i++) {
    37                 cur_x = q.front().first;
    38                 cur_y = q.front().second;
    39                 q.pop();
    40                 if(board[cur_x][cur_y]=='M') {
    41                     board[cur_x][cur_y]='X';
    42                     continue;
    43                 }
    44                 int cM = countM(cur_x,cur_y,board);
    45                 if(cM>0) {
    46                     board[cur_x][cur_y]=cM+'0';
    47                     continue;
    48                 }
    49                 board[cur_x][cur_y]='B';
    50                 for(auto d:dir) {
    51                     x = cur_x+d[0], y = cur_y+d[1];
    52                     //printf("x:%d, y:%d
    ",x,y);
    53                     if(x<0 || y<0 || x>=n || y>=m || board[x][y]!='E') continue;
    54                     //printf("inqueue:(%d,%d)=%c
    ",x,y,board[x][y]);
    55                     q.push({x,y});
    56                     board[x][y]='B';
    57                     //优化,第一次判断立即将该点设为非E,之后其他方向点判断时,直接continue
    58                     //不用加入queue.保证一个cell只加入queue一次。
    59                     
    60                 }
    61             }
    62         }
    63         return board;
    64     }
    65 };
  • 相关阅读:
    ExtJs中动态加载机制研究(转)
    ExtJs4 学习3 combox自动加载的例子
    Extjs 4学习2
    ExtJS 4学习
    javascript学习(知识点整理)
    ExtJS智能提示工具spket安装与破解
    eclipse慢 优化(转)
    疯狂学习java web5(SSI框架)
    疯狂学习java web4(jsp)
    疯狂学习java web3(javaScript)
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/14476299.html
Copyright © 2011-2022 走看看