529. 扫雷游戏(BFS)
529. 扫雷游戏
让我们一起来玩扫雷游戏!
给你一个大小为 m x n 二维字符矩阵 board ,表示扫雷游戏的盘面,其中:
'M'代表一个 未挖出的 地雷,'E'代表一个 未挖出的 空方块,'B'代表没有相邻(上,下,左,右,和所有4个对角线)地雷的 已挖出的 空白方块,- 数字(
'1'到'8')表示有多少地雷与这块 已挖出的 方块相邻, 'X'则表示一个 已挖出的 地雷。
给你一个整数数组 click ,其中 click = [clickr, clickc] 表示在所有 未挖出的 方块('M' 或者 'E')中的下一个点击位置(clickr 是行下标,clickc 是列下标)。
根据以下规则,返回相应位置被点击后对应的盘面:
- 如果一个地雷(
'M')被挖出,游戏就结束了- 把它改为'X'。 - 如果一个 没有相邻地雷 的空方块(
'E')被挖出,修改它为('B'),并且所有和其相邻的 未挖出 方块都应该被递归地揭露。 - 如果一个 至少与一个地雷相邻 的空方块(
'E')被挖出,修改它为数字('1'到'8'),表示相邻地雷的数量。 - 如果在此次点击中,若无更多方块可被揭露,则返回盘面。
示例 1:
输入:board = [["E","E","E","E","E"],["E","E","M","E","E"],["E","E","E","E","E"],["E","E","E","E","E"]], click = [3,0] 输出:[["B","1","E","1","B"],["B","1","M","1","B"],["B","1","1","1","B"],["B","B","B","B","B"]]
示例 2:
输入:board = [["B","1","E","1","B"],["B","1","M","1","B"],["B","1","1","1","B"],["B","B","B","B","B"]], click = [1,2] 输出:[["B","1","E","1","B"],["B","1","X","1","B"],["B","1","1","1","B"],["B","B","B","B","B"]]
提示:
m == board.lengthn == board[i].length1 <= m, n <= 50board[i][j]为'M'、'E'、'B'或数字'1'到'8'中的一个click.length == 20 <= clickr < m0 <= clickc < nboard[clickr][clickc]为'M'或'E'
1 class Solution { 2 public: 3 // 图中8个方向,顺时针:正上、右上、右、右下、正下、左下、左、左上 4 vector<vector<int>> g_direction = {{-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}}; 5 // 是否在游戏界面范围内 6 bool isInArea(int row, int col, int x, int y) { 7 return (x >= 0 && x < row && y >= 0 && y < col); 8 } 9 void bfs(vector<vector<char>>& board, int x, int y) { 10 queue<pair<int, int>> q; 11 int row = board.size(); 12 int col = board[0].size(); 13 vector<vector<bool>> visited(row, vector<bool>(col, 0)); 14 q.push(make_pair(x, y)); 15 visited[x][y] = true; 16 while (!q.empty()) { 17 auto pos = q.front(); 18 q.pop(); 19 int cnt = 0; 20 int x = pos.first; 21 int y = pos.second; 22 for (auto &direction : g_direction) { 23 int nextX = x + direction[0]; 24 int nextY = y + direction[1]; 25 if (!isInArea(row, col, nextX, nextY)) { 26 continue; 27 } 28 if (board[nextX][nextY] == 'M') { 29 cnt++; 30 } 31 } 32 if (cnt > 0) { 33 // 规则 3 34 board[x][y] = cnt + '0'; 35 } else { 36 // 规则 2 37 board[x][y] = 'B'; 38 for (auto &direction : g_direction) { 39 int nextX = x + direction[0]; 40 int nextY = y + direction[1]; 41 // 这里不需要在存在 B 的时候继续扩展,因为 B 之前被点击的时候已经被扩展过了 42 if (!isInArea(row, col, nextX, nextY) || board[nextX][nextY] != 'E' || visited[nextX][nextY]) { 43 continue; 44 } 45 q.push(make_pair(nextX, nextY)); 46 visited[nextX][nextY] = true; 47 } 48 } 49 } 50 } 51 52 vector<vector<char>> updateBoard(vector<vector<char>>& board, vector<int>& click) { 53 int x = click[0], y = click[1]; 54 if (board[x][y] == 'M') { 55 // 规则 1 56 board[x][y] = 'X'; 57 } else { 58 bfs(board, x, y); 59 } 60 return board; 61 } 62 };
浙公网安备 33010602011771号