Problem p01493 (C++)

Buggy submission (status: Memory Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;

#define rep(i, x, y) for (int i = (x); i < (y); ++i)
#define debug(x) #x << "=" << (x)

#ifdef DEBUG
#define _GLIBCXX_DEBUG
#define print(x) std::cerr << debug(x) << " (L:" << __LINE__ << ")" << std::endl
#else
#define print(x)
#endif

const int inf = 1e9;
const int64_t inf64 = 1e18;
const double eps = 1e-9;

template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
  os << "[";
  for (const auto &v : vec) {
    os << v << ",";
  }
  os << "]";
  return os;
}

void solve() {
  int v;
  cin >> v;
  vector<vector<char>> a(v, vector<char>(v));
  rep(i, 0, v) rep(j, 0, v) cin >> a[i][j];

  int x = 0, y = 0, f = 0;
  {
    vector<bool> used(v);
    rep(i, 0, v) {
      if (used[i])
        continue;
      used[i] = true;
      vector<int> vi;
      queue<int> que;
      que.push(i);
      while (!que.empty()) {
        int p = que.front();
        que.pop();
        vi.push_back(p);
        rep(j, 0, v) {
          if (used[j] or a[p][j] == 'N')
            continue;
          que.push(j);
          used[j] = true;
        }
      }
      if (vi.size() % 2 == 0)
        ++x;
      else
        ++y;
      int cnt = 0;
      rep(j, 0, vi.size())
          rep(k, j + 1, vi.size()) if (a[vi[j]][vi[k]] == 'Y')++ cnt;
      f = (f + vi.size() * (vi.size() - 1) / 2 - cnt + 2) % 2;
    }
  }

  vector<vector<vector<bool>>> dp(v + 1), done(v + 1);
  rep(i, 0, v + 1) {
    dp[i].assign(v - i + 1, vector<bool>(2));
    done[i].assign(v - i + 1, vector<bool>(2));
  }
  function<bool(int, int, int)> rec = [&](int x, int y, int f) {
    if (done[x][y][f])
      return dp[x][y][f];
    done[x][y][f] = true;
    if ((x == 1 and y == 0) or (x == 0 and y == 1))
      return dp[x][y][f] = true;
    bool res = false;
    if (f == 1)
      res |= !rec(x, y, 1 - f);
    if (x >= 2)
      res |= !rec(x - 1, y, 1 - f);
    if (y >= 2)
      res |= !rec(x + 1, y - 2, f);
    if (x >= 1 and y >= 1)
      res |= !rec(x - 1, y, 1 - f);
    return dp[x][y][f] = res;
  };

  if (rec(x, y, f))
    cout << "Taro" << endl;
  else
    cout << "Hanako" << endl;
}

int main() {
  std::cin.tie(0);
  std::ios::sync_with_stdio(false);
  cout.setf(ios::fixed);
  cout.precision(10);
  solve();
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;

#define rep(i, x, y) for (int i = (x); i < (y); ++i)
#define debug(x) #x << "=" << (x)

#ifdef DEBUG
#define _GLIBCXX_DEBUG
#define print(x) std::cerr << debug(x) << " (L:" << __LINE__ << ")" << std::endl
#else
#define print(x)
#endif

const int inf = 1e9;
const int64_t inf64 = 1e18;
const double eps = 1e-9;

template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
  os << "[";
  for (const auto &v : vec) {
    os << v << ",";
  }
  os << "]";
  return os;
}

void solve() {
  int v;
  cin >> v;
  vector<vector<char>> a(v, vector<char>(v));
  rep(i, 0, v) rep(j, 0, v) cin >> a[i][j];

  int x = 0, y = 0, f = 0;
  {
    vector<bool> used(v);
    rep(i, 0, v) {
      if (used[i])
        continue;
      used[i] = true;
      vector<int> vi;
      queue<int> que;
      que.push(i);
      while (!que.empty()) {
        int p = que.front();
        que.pop();
        vi.push_back(p);
        rep(j, 0, v) {
          if (used[j] or a[p][j] == 'N')
            continue;
          que.push(j);
          used[j] = true;
        }
      }
      if (vi.size() % 2 == 0)
        ++x;
      else
        ++y;
      int cnt = 0;
      rep(j, 0, vi.size())
          rep(k, j + 1, vi.size()) if (a[vi[j]][vi[k]] == 'Y')++ cnt;
      f = (f + vi.size() * (vi.size() - 1) / 2 - cnt + 2) % 2;
    }
  }

  static bool dp[1001][1001][2] = {}, done[1001][1001][2] = {};
  function<bool(int, int, int)> rec = [&](int x, int y, int f) {
    if (done[x][y][f])
      return dp[x][y][f];
    done[x][y][f] = true;
    if ((x == 1 and y == 0) or (x == 0 and y == 1))
      return dp[x][y][f] = true;
    bool res = false;
    if (f == 1)
      res |= !rec(x, y, 1 - f);
    if (x >= 2)
      res |= !rec(x - 1, y, 1 - f);
    if (y >= 2)
      res |= !rec(x + 1, y - 2, f);
    if (x >= 1 and y >= 1)
      res |= !rec(x - 1, y, 1 - f);
    return dp[x][y][f] = res;
  };

  if (rec(x, y, f))
    cout << "Taro" << endl;
  else
    cout << "Hanako" << endl;
}

int main() {
  std::cin.tie(0);
  std::ios::sync_with_stdio(false);
  cout.setf(ios::fixed);
  cout.precision(10);
  solve();
  return 0;
}