Minesweeper

来源:互联网 发布:逆战账号数据异常 编辑:程序博客网 时间:2024/04/27 03:19

Description
You are given a 2D char matrix representing the game board. ‘M’ represents an unrevealed mine, ‘E’ represents an unrevealed empty square, ‘B’ represents a revealed blank square that has no adjacent (above, below, left, right, and all 4 diagonals) mines, digit (‘1’ to ‘8’) represents how many mines are adjacent to this revealed square, and finally ‘X’ represents a revealed mine.

Now given the next click position (row and column indices) among all the unrevealed squares (‘M’ or ‘E’), return the board after revealing this position according to the following rules:

If a mine (‘M’) is revealed, then the game is over - change it to ‘X’.
If an empty square (‘E’) with no adjacent mines is revealed, then change it to revealed blank (‘B’) and all of its adjacent unrevealed squares should be revealed recursively.
If an empty square (‘E’) with at least one adjacent mine is revealed, then change it to a digit (‘1’ to ‘8’) representing the number of adjacent mines.
Return the board when no more squares will be revealed.
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’]]

Explanation:
这里写图片描述

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’]]

Explanation:
这里写图片描述
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.
解题思路:
这道题目说了那么多,其实就是让我们写一个表示在玩扫雷时,一次点击之后游戏盘面的变化情况函数。题目保证了每一次的点击都是有效的,即只点击哪些还没有被揭开的方格。因此,要揭开的方格蕴含了三种情况。第一,刚好挖到了地雷,把该方格设置为‘X’,游戏结束。第二,这是一个空方格,空方格就是指以该方格为中心的外围一圈方格中没有埋地雷,这使把该方格置为‘B’,并递归地揭开围绕着它的一圈方格。第三,围绕该方格的一圈方格中埋有1到8个地雷,把该方格设置为周围一圈埋着的地雷总数。所以只需要根据这三种情况设置结果的输出即可。在第二和第三种情况中,需要统计周围的地雷数量,所以可以用一个函数来统计上下左右以及四个对角的情况。对于第三种情况,使用广搜的思想,建立一个队列,把环绕着中心方格的一圈方格中哪些空方格入队,然后把出队一个方格,以它为中心重复上面的操作。程序代码如下:

class Solution {private:    //返回空方格的数量    int is_empty(int r, int c, vector<vector<char>> & board) {          int count = 0;        int row = board.size();        int col = board[0].size();        if (r - 1 >= 0 && board[r - 1][c] == 'M')  //往上检查            count++;        if (r + 1 < row && board[r + 1][c] == 'M') //往下检查            count++;        if (c - 1 >= 0 && board[r][c - 1] == 'M')  //往左检查            count++;        if (c + 1 < col && board[r][c + 1] == 'M')  //往右检查            count++;        if (r - 1 >= 0 && c - 1 >= 0 && board[r - 1][c - 1] == 'M')  //往左上检查            count++;        if (r - 1 >= 0 && c + 1 < col && board[r - 1][c + 1] == 'M') //往右上检查            count++;        if (r + 1 < row && c - 1 >= 0 && board[r + 1][c - 1] == 'M') //往左下检查            count++;        if (r + 1 < row && c + 1 < col && board[r + 1][c + 1] == 'M') //往右上检查            count++;        return count;    }    void bfs(vector<int>& position, vector<vector<char>> & board) {        int row = board.size();        int col = board[0].size();        int r = position[0];        int c = position[1];        if (!is_empty(r, c, board)) {            queue<vector<int>> q;            q.push(position);            while (!q.empty()) {                vector<int> temp = q.front();                q.pop();                r = temp[0];                c = temp[1];                int count;                if (r - 1 >= 0 && board[r - 1][c] == 'E') {                    count = is_empty(r - 1, c, board);                    if (count)                         board[r - 1][c] = '0' + count; //设置地雷个数                    else {                        vector<int> t;                        board[r - 1][c] = 'B'; //要注意把方格设置为'B',防止重复入队                        t.push_back(r - 1);                        t.push_back(c);                        q.push(t);                    }                }                if (r + 1 < row && board[r + 1][c] == 'E') {                    count = is_empty(r + 1, c, board);                    if (count)                         board[r + 1][c] = '0' + count;                    else {                        vector<int> t;                        board[r + 1][c] = 'B';                        t.push_back(r + 1);                        t.push_back(c);                        q.push(t);                    }                }                if (c - 1 >= 0 && board[r][c - 1] == 'E') {                    count = is_empty(r, c - 1, board);                    if (count)                         board[r][c - 1] = '0' + count;                    else {                        vector<int> t;                        board[r][c - 1] = 'B';                        t.push_back(r);                        t.push_back(c - 1);                        q.push(t);                    }                }               if (c + 1 < col && board[r][c + 1] == 'E') {                    count = is_empty(r, c + 1, board);                    if (count)                         board[r][c + 1] = '0' + count;                    else {                        vector<int> t;                        board[r][c + 1] = 'B';                        t.push_back(r);                        t.push_back(c + 1);                        q.push(t);                    }                }                 if (c - 1 >= 0 && r - 1 >= 0 && board[r - 1][c - 1] == 'E') {                    count = is_empty(r - 1, c - 1, board);                    if (count)                         board[r - 1][c - 1] = '0' + count;                    else {                        vector<int> t;                        board[r - 1][c - 1] = 'B';                        t.push_back(r - 1);                        t.push_back(c - 1);                        q.push(t);                    }                }                if (c + 1 < col && r - 1 >= 0 && board[r - 1][c + 1] == 'E') {                    count = is_empty(r - 1, c + 1, board);                    if (count)                         board[r - 1][c + 1] = '0' + count;                    else {                        vector<int> t;                        board[r - 1][c + 1] = 'B';                        t.push_back(r - 1);                        t.push_back(c + 1);                        q.push(t);                    }                }               if (c - 1 >= 0 && r + 1 <row && board[r + 1][c - 1] == 'E') {                    count = is_empty(r + 1, c - 1, board);                    if (count)                         board[r + 1][c - 1] = '0' + count;                    else {                        vector<int> t;                        board[r + 1][c - 1] = 'B';                        t.push_back(r + 1);                        t.push_back(c - 1);                        q.push(t);                    }                }               if (c + 1 < col && r + 1 <row && board[r + 1][c + 1] == 'E') {                    count = is_empty(r + 1, c + 1, board);                    if (count)                         board[r + 1][c + 1] = '0' + count;                    else {                        vector<int> t;                        board[r + 1][c + 1] = 'B';                        t.push_back(r + 1);                        t.push_back(c + 1);                        q.push(t);                    }                }            }        }    }public:    vector<vector<char>> updateBoard(vector<vector<char>>& board, vector<int>& click) {        int row = click[0];        int col = click[1];        if (board[row][col] == 'M') {            board[row][col] = 'X';            return board;        }        int count = is_empty(row, col, board);        if (count) {            board[row][col] = '0' + count;            return board;        }        board[row][col] = 'B';        bfs(click, board);        return board;    }};
0 0