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

    ▶ 扫雷的扩展判定。已知棋盘上所有点的情况(雷区 'M',已翻开空白区 'B',未翻开空白区 'E',数字区 '1' ~ '8'),现在给定一个点击位置(一定在空白区域),若命中雷区则将被命中的 M 改为 X,若命中空白区则将点击位置扩展为带有数字边界的安全区。

    ● 自己的解法,28 ms,深度优先遍历。改善了边界判定的方法,以后写类似的矩阵函数的时候可以借鉴。实际上可以在 extend 开头判定 click 是否在棋盘范围内,以后就可以强行 8 个方向搜索(见后面大佬的代码)

     1 class Solution
     2 {
     3 public:
     4     vector<vector<char>> updateBoard(vector<vector<char>>& board, vector<int>& click)
     5     {
     6         if (board[click[0]][click[1]] == 'M')
     7         {
     8             board[click[0]][click[1]] = 'X';
     9             return board;
    10         }
    11         extend(board, click);
    12         return board;
    13     }
    14     void extend(vector<vector<char>>& board, vector<int>& click)
    15     {
    16         const int row = board.size(), col = board[0].size(), rowClick = click[0], colClick = click[1];        
    17         char location = ~0;
    18         int count = 0;
    19         vector<int> tempClick;
    20         // 计算当前位置的相邻情况,location从左边起 8 位分别表示 右,右上,上,左上,左,左下,下,右下 是否有相邻块
    21         if (colClick % col == col - 1)  // 右,11000001
    22             location &= ~193;
    23         if (rowClick == 0)              // 上,01110000
    24             location &= ~112;    
    25         if (colClick % col == 0)        // 左,00011100
    26             location &= ~28;
    27         if (rowClick == row - 1)        // 下,00000111
    28             location &= ~7;
    29         // 统计周围雷数计数,从右开始,逆时针方向搜索
    30         if (location & 1 << 7 && board[rowClick][colClick + 1] == 'M')
    31             count++;
    32         if (location & 1 << 6 && board[rowClick - 1][colClick + 1] == 'M')
    33             count++;
    34         if (location & 1 << 5 && board[rowClick - 1][colClick] == 'M')
    35             count++;
    36         if (location & 1 << 4 && board[rowClick - 1][colClick - 1] == 'M')
    37             count++;
    38         if (location & 1 << 3 && board[rowClick][colClick - 1] == 'M')
    39             count++;
    40         if (location & 1 << 2 && board[rowClick + 1][colClick - 1] == 'M')
    41             count++;
    42         if (location & 1 << 1 && board[rowClick + 1][colClick] == 'M')
    43             count++;
    44         if (location & 1 << 0 && board[rowClick + 1][colClick + 1] == 'M')
    45             count++;        
    46         if (count)// 周围有雷,本地为数字,停止搜索
    47         {
    48             board[rowClick][colClick] = count + '0';
    49             return;
    50         }        
    51         board[rowClick][colClick] = 'B';// 周围无雷,本地为安全区,继续搜索
    52         if (location & 1 << 7 && board[rowClick][colClick + 1] == 'E')
    53             extend(board, tempClick = { rowClick, colClick + 1 }); 
    54         if (location & 1 << 6 && board[rowClick - 1][colClick + 1] == 'E')
    55             extend(board, tempClick = { rowClick - 1, colClick + 1 });
    56         if (location & 1 << 5 && board[rowClick - 1][colClick] == 'E')
    57             extend(board, tempClick = { rowClick - 1, colClick });
    58         if (location & 1 << 4 && board[rowClick - 1][colClick - 1] == 'E')
    59             extend(board, tempClick = { rowClick - 1, colClick - 1 });
    60         if (location & 1 << 3 && board[rowClick][colClick - 1] == 'E')
    61             extend(board, tempClick = { rowClick, colClick - 1 });
    62         if (location & 1 << 2 && board[rowClick + 1][colClick - 1] == 'E')
    63             extend(board, tempClick = { rowClick + 1, colClick - 1 });
    64         if (location & 1 << 1 && board[rowClick + 1][colClick] == 'E')
    65             extend(board, tempClick = { rowClick + 1, colClick });
    66         if (location & 1 << 0 && board[rowClick + 1][colClick + 1] == 'E')
    67             extend(board, tempClick = { rowClick + 1, colClick + 1 });
    68         return;
    69     }
    70 };

    ● 大佬的代码,38 ms,深度优先遍历,与后面的广度优先遍历在格式上保持一致

     1 class Solution
     2 {
     3 public:
     4     vector<vector<char>> updateBoard(vector<vector<char>>& board, vector<int>& click)
     5     {
     6         int m = board.size(), n = board[0].size(), row = click[0], col = click[1];
     7         int count, i, j, r, c;
     8         vector<int>tempClick;
     9         if (board[row][col] == 'M')
    10         {
    11             board[row][col] = 'X';
    12             return board;
    13         }
    14         for (count = 0, i = -1; i < 2; i++)
    15         {
    16             for (j = -1; j < 2; j++)
    17             {
    18                 if (i == 0 && j == 0)
    19                     continue;
    20                 r = row + i, c = col + j;
    21                 if (r < 0 || r >= m || c < 0 || c < 0 || c >= n)
    22                     continue;
    23                 if (board[r][c] == 'M' || board[r][c] == 'X')
    24                     count++;
    25             }
    26         }
    27         if (count)
    28         {
    29             board[row][col] = (char)(count + '0');
    30             return board;
    31         }                
    32         for (board[row][col] = 'B', i = -1; i < 2; i++)
    33         {
    34             for (j = -1; j < 2; j++)
    35             {
    36                 if (i == 0 && j == 0)
    37                     continue;
    38                 r = row + i, c = col + j;
    39                 if (r < 0 || r >= m || c < 0 || c < 0 || c >= n)
    40                     continue;
    41                 if (board[r][c] == 'E')                 
    42                     updateBoard(board, tempClick = { r, c });
    43             }
    44         }        
    45         return board;
    46     }
    47 };

    ● 大佬的广度优先遍历,31 ms,最快的解法算法与之相同,但维护一个 unordered_set<int> 用于保存已经访问过的点来防止重复访问

     1 class Solution
     2 {
     3 public:
     4     vector<vector<char>> updateBoard(vector<vector<char>>& board, vector<int>& click)
     5     {
     6         const int m = board.size(), n = board[0].size();
     7         queue<vector<int>> q;
     8         vector<int> cell;
     9         int row, col, count, i, j, r, c;
    10         for (q.push(click); !q.empty();)
    11         {
    12             cell = q.front(),q.pop();
    13             row = cell[0], col = cell[1];
    14             if (board[row][col] == 'M')
    15             {
    16                 board[row][col] = 'X';
    17                 continue;
    18             }                                  
    19             for (count = 0, i = -1; i < 2; i++)
    20             {
    21                 for (j = -1; j < 2; j++)
    22                 {
    23                     if (i == 0 && j == 0)
    24                         continue;
    25                     r = row + i, c = col + j;
    26                     if (r < 0 || r >= m || c < 0 || c < 0 || c >= n)
    27                         continue;
    28                     if (board[r][c] == 'M' || board[r][c] == 'X')
    29                         count++;
    30                 }
    31             }
    32             if (count)
    33             {
    34                 board[row][col] = (char)(count + '0');
    35                 continue;
    36             }            
    37             for (board[row][col] = 'B', i = -1; i < 2; i++)
    38             {
    39                 for (j = -1; j < 2; j++)
    40                 {
    41                     if (i == 0 && j == 0) 
    42                         continue;
    43                     r = row + i, c = col + j;
    44                     if (r < 0 || r >= m || c < 0 || c < 0 || c >= n)
    45                         continue;
    46                     if (board[r][c] == 'E')
    47                     {
    48                         q.push(vector<int>{r, c});
    49                         board[r][c] = 'B';
    50                     }
    51                 }
    52             }
    53         }
    54         return board;
    55     }
    56 };
  • 相关阅读:
    权当这是开始吧
    rabbitmq实现一台服务器同时给指定部分的consumer发送消息(tp框架)(第六篇)
    部分替换mysql表中某列的字段
    rabbitmq实现一台服务器同时给指定部分的consumer发送消息(tp框架)(第五篇)
    rabbitmq实现一台服务器同时给所有的consumer发送消息(tp框架)(第四篇)
    rabbit服务器挂掉以后,保证队列消息还存在(tp框架)(第三篇)
    HDU 1114 Piggy-Bank (poj1384)
    01背包
    等价表达式(noip2005)
    机器翻译(noip2010)
  • 原文地址:https://www.cnblogs.com/cuancuancuanhao/p/8411107.html
Copyright © 2011-2022 走看看