(Analysis by Spencer Compton)

For Bessie to have an attainable winning tic-tac-toe board configuration, she must do so through a sequence of movements and encountering pieces of paper. Key to this problem is conceptualizing a "state" that encompasses Bessie's situation at any point in time in such a process.

One aspect of Bessie's state would be what her current tic-tac-toe board looks like. However, there may be multiple positions in the maze Bessie could be at with a particular board state (which may affect the potential board states she could later reach).

Another aspect of Bessie's state would be her position in the maze. However, there could be multiple board states Bessie could have when she is at a particular position in the maze.

Fortunately, when we combine both of these pieces of information, this perfectly encapsulates Bessie's state in the process. Our goal is to first figure out which states Bessie could possibly reach, and then how many distinct winning tic-tac-toe board configurations are there such that Bessie can reach a state with that board configuration.

To find all states Bessie can reach, we can use a depth first search (DFS) starting at Bessie's starting position in the maze and an empty tic-tac-toe board. From each state, we can try recursing a further level by trying to move in each possible direction in the maze. To make sure our DFS does not take very long, we will keep track of which states we have visited so we do not need to revisit them (e.g. we can have a boolean array that indicates whether or not we have visited each state). Note that if we use a set to keep track of these states, this might cause a solution to exceed the time limit of some test cases. Instead, for example, we can convert our board state to a number and have a 3-dimensional visited array with dimensions for Bessie's row, column, and board state (converted to an integer). Since there are $25^2$ possible locations in the maze and $\le 3^9$ possible board states, our number of states is bounded by $25^2 \times 3^9$.

Our depth first search will enable us to determine exactly which states Bessie could obtain, and then we can finally count the number of distinct winning boards among boards where there is some state such that Bessie could have that board.

Brian Dean's code:

#include <cstdio>
#include <set>
using namespace std;
 
int N;
char board[25][25][3];
set<int> answers;
bool beenthere[25][25][19683];
int pow3[10];
 
bool test_win(int b)
{
  int cells[3][3];
  for (int i=0; i<3; i++)
    for (int j=0; j<3; j++) {
      cells[i][j] = b%3;
      b /= 3;
    }
  for (int r=0; r<3; r++) {
    if (cells[r][0] == 1 && cells[r][1] == 2 && cells[r][2] == 2) return true;
    if (cells[r][0] == 2 && cells[r][1] == 2 && cells[r][2] == 1) return true;
  }
  for (int c=0; c<3; c++) {
    if (cells[0][c] == 1 && cells[1][c] == 2 && cells[2][c] == 2) return true;
    if (cells[0][c] == 2 && cells[1][c] == 2 && cells[2][c] == 1) return true;
  }
  if (cells[0][0] == 1 && cells[1][1] == 2 && cells[2][2] == 2) return true;
  if (cells[0][0] == 2 && cells[1][1] == 2 && cells[2][2] == 1) return true;
  if (cells[2][0] == 1 && cells[1][1] == 2 && cells[0][2] == 2) return true;
  if (cells[2][0] == 2 && cells[1][1] == 2 && cells[0][2] == 1) return true;
  return false;
}
 
void dfs(int i, int j, int b)
{
  if (beenthere[i][j][b]) return;
  beenthere[i][j][b] = true;
  if (board[i][j][0]=='M' || board[i][j][0]=='O') {
    int r = board[i][j][1]-'1', c = board[i][j][2]-'1', idx = r*3+c;
    int current_char = (b / pow3[idx]) % 3;
    if (current_char == 0) {
      int new_char = board[i][j][0]=='M' ? 1 : 2;
      b = (b % pow3[idx]) + new_char * pow3[idx] + (b - b % pow3[idx+1]);
      if (!beenthere[i][j][b] && test_win(b)) { answers.insert(b); return; }
      beenthere[i][j][b] = true;
    }
  }
  if (board[i-1][j][0] != '#') dfs(i-1,j,b);
  if (board[i+1][j][0] != '#') dfs(i+1,j,b);
  if (board[i][j-1][0] != '#') dfs(i,j-1,b);
  if (board[i][j+1][0] != '#') dfs(i,j+1,b);
}
 
int main(void)
{
  int bess_i, bess_j, bstate = 0;
  pow3[0] = 1;
  for (int i=1; i<=9; i++) pow3[i] = pow3[i-1]*3;
  scanf ("%d", &N);
  for (int i=0; i<N; i++)
    for (int j=0; j<N; j++) {
      scanf (" %c%c%c", &board[i][j][0], &board[i][j][1], &board[i][j][2]);
      if (board[i][j][0] == 'B') { bess_i = i; bess_j = j; }
    }
  dfs(bess_i, bess_j, bstate);
  printf ("%d\n", (int)answers.size()); 
}