class Solution {
public:
using TUPLE = tuple<int, int>;
void solve(vector<vector<char>>& board) {
int rows = board.size();
if (rows == 0) return;
int cols = board[0].size();
vector<vector<int> > checkedTb(rows, vector<int>(cols, 0));
for (int r = 0; r != rows; ++r) {
for (int c = 0; c != cols; ++c) {
if (board[r][c] == 'X' || checkedTb[r][c] == 1 ) continue;
checkedTb[r][c] = 1;
solver(board, make_tuple(r, c), checkedTb);
}
}
}
private:
void solver(vector<vector<char> >& board, TUPLE t, vector<vector<int> >& checkedTb) {
int rows = board.size();
int cols = board[0].size();
bool open = (get<0>(t) == rows - 1 || get<0>(t) == 0 || get<1>(t) == cols - 1 || get<1>(t) == 0);
vector<TUPLE> points{ t };
deque<TUPLE> dq{ t };
while (!dq.empty()) {
int n = dq.size();
for (int i = 0; i != n; ++i) {
TUPLE tp = dq.front();
int r = get<0>(tp);
int c = get<1>(tp);
if (r != 0 && board[r - 1][c] == 'O' && checkedTb[r - 1][c] == 0) {
if (!open && r - 1 == 0)
open = true;
points.emplace_back(make_tuple(r - 1, c));
dq.emplace_back(make_tuple(r - 1, c));
checkedTb[r - 1][c] = 1;
}
if (r != rows - 1 && board[r + 1][c] == 'O' && checkedTb[r + 1][c] == 0) {
if (!open && r + 1 == rows - 1)
open = true;
points.emplace_back(make_tuple(r + 1, c));
dq.emplace_back(make_tuple(r + 1, c));
checkedTb[r + 1][c] = 1;
}
if (c != cols - 1 && board[r][c + 1] == 'O' && checkedTb[r][c + 1] == 0) {
if (!open && c + 1 == cols - 1)
open = true;
points.emplace_back(make_tuple(r, c + 1));
dq.emplace_back(make_tuple(r, c + 1));
checkedTb[r][c + 1] = 1;
}
if (c != 0 && board[r][c - 1] == 'O' && checkedTb[r][c - 1] == 0) {
if (!open && c - 1 == 0)
open = true;
points.emplace_back(make_tuple(r, c - 1));
dq.emplace_back(make_tuple(r, c - 1));
checkedTb[r][c - 1] = 1;
}
dq.pop_front();
}
}
if (!open) {
for (auto & point : points) {
int r = get<0>(point);
int c = get<1>(point);
board[r][c] = 'X';
}
}
return;
}
};