class Solution {
unordered_set<string> visited;
inline string hash(int r, int c) {
return to_string(r) + "#" + to_string(c);
}
void check(vector<vector<char>>& board,
int row,
int col,
vector<vector<int>>& blocks,
int& mines) {
int width = board[0].size();
int height = board.size();
int dirs[] = {
//left
-1, 0,
//right
1, 0,
//up
0, -1,
//down
0, 1,
//topleft
-1, -1,
//topright
1, -1,
//bottomleft
-1, 1,
//bottomright
1, 1
};
for (int i = 0; i < 8; ++i) {
int dr = row + dirs[2*i];
int dc = col + dirs[2*i + 1];
if (dr < 0 || dr > height - 1 || dc < 0 || dc > width - 1) {
continue;
}
if (board[dr][dc] == 'M') {
mines++;
}
else if (board[dr][dc] == 'E') {
blocks.push_back({dr, dc});
}
}
}
void reveal(vector<vector<char>>& board, int row, int col) {
auto key = hash(row, col);
if (visited.find(key) != visited.end()) return;
visited.insert(key);
vector<vector<int>> blocks;
int mineCount = 0;
check(board, row, col, blocks, mineCount);
if (mineCount > 0) {
board[row][col] = '0' + mineCount;
return;
}
board[row][col] = 'B';
for (auto& b : blocks) {
reveal(board, b[0], b[1]);
}
}
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;
}
reveal(board, row, col);
return board;
}
};