Problem p01493 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <bitset>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
#define X first
#define Y second
#define pb push_back
#define rep(X, Y) for (int(X) = 0; (X) < (Y); ++(X))
#define rrep(X, Y) for (int(X) = (Y - 1); (X) >= 0; --(X))
#define repe(X, Y) for ((X) = 0; (X) < (Y); ++(X))
#define peat(X, Y) for (; (X) < (Y); ++(X))
#define all(X) (X).begin(), (X).end()
#define rall(X) (X).rbegin(), (X).rend()

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
template <class T> ostream &operator<<(ostream &os, const vector<T> &t) {
  os << "{";
  rep(i, t.size()) { os << t[i] << ","; }
  os << "}" << endl;
  return os;
}
template <class S, class T>
ostream &operator<<(ostream &os, const pair<S, T> &t) {
  return os << "(" << t.first << "," << t.second << ")";
}
typedef vector<string> Graph;
int used[1123], v;
int dfs(Graph &g, int p) {
  if (used[p])
    return 0;
  used[p] = 1;
  int re = 1;
  rep(i, v) if (g[p][i] == 'Y') re += dfs(g, i);
  return re;
}

int memo[112][2][2][2][2];

int solve(int n, int edge, int even, int rem, int to) {
  //  cout<<"("<<n<<","<<edge<<","<<even<<","<<rem<<","<<to<<")"<<endl;
  int re = 0;
  if (n == 2 && even == 0)
    return to == 1;
  if (n == 0 && even == 2)
    return to == 0;
  if (memo[n][edge][even][rem][to])
    return memo[n][edge][even][rem][to] - 1;
  if (even == 1 && to == 0) {
    re = 1;
  } else if (!rem) {
    re = 1 - solve(n - 2 + 2 * even, edge + even, 1 - even, 1, 1 - to);
  } else {
    if (even) {
      re |= 1 - solve(n, 1 - edge, 0, 1, 1 - to);
      if (rem % 2)
        re |= 1 - solve(n, 1 - edge, 1, 0, 1 - to);
    } else {
      re |= 1 - solve(n - 2, edge, 1, 1, 1 - to);
      if (rem % 2)
        re |= 1 - solve(n - 2, edge, 1, 0, 1 - to);
    }
  }
  memo[n][edge][even][rem][to] = re + 1;
  //  cout<<"("<<n<<","<<edge<<","<<even<<","<<rem<<","<<to<<"):"<<re<<endl;
  return re;
}

int main() {
  ios_base::sync_with_stdio(false);
  cout << fixed << setprecision(0);
  int i, j, k, e = 0;
  cin >> v;
  Graph strs(v);
  vector<int> ccs;
  rep(i, v) {
    cin >> strs[i];
    e += count(all(strs[i]), 'Y');
  }
  e /= 2;
  //  cout<<e<<endl;
  rep(i, v) if (!used[i]) ccs.pb(dfs(strs, i));
  int rem = 0;
  for (int cc : ccs)
    rem += (cc - 1) * cc / 2;
  rem -= e;
  //    cout<<ccs<<endl;
  if (v % 2) {
    cout << (e % 2 == v % 4 / 2 ? "Hanako" : "Taro") << endl;
  } else {
    int oc = 0, ec = ccs.size();
    rep(i, ccs.size()) oc += ccs[i] % 2;
    ec -= oc;
    //    cout<<ec<<","<<oc<<endl;
    if (ec == 0) {
      /*if(ccs.size()==2){
        cout<<"Hanako"<<endl;
        return 0;
        }*/
      //     cout<<"odd:"<<solve(oc,rem%2,0,rem>0,1)<<endl;
      //      cout<<"even:"<<solve(oc,rem%2,0,rem>0,0)<<endl;
      cout << (e % 2 == v / 2 % 2 && solve(oc, rem % 2, 0, rem > 0, 1) ||
                       e % 2 != v / 2 % 2 && solve(oc, rem % 2, 0, rem > 0, 0)
                   ? "Taro"
                   : "Hanako")
           << endl;
    } else if (ec == 1) {
      int odd = 0;
      cout << (solve(oc, rem % 2, 1, rem > 0, 1) || e % 2 != v / 2 % 2
                   ? "Taro"
                   : "Hanako")
           << endl;
    } else {
      cout << (e % 2 != v / 2 % 2 ? "Taro" : "Hanako") << endl;
    }
  }
  return 0;
}

Fixed submission:
#include <algorithm>
#include <bitset>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
#define X first
#define Y second
#define pb push_back
#define rep(X, Y) for (int(X) = 0; (X) < (Y); ++(X))
#define rrep(X, Y) for (int(X) = (Y - 1); (X) >= 0; --(X))
#define repe(X, Y) for ((X) = 0; (X) < (Y); ++(X))
#define peat(X, Y) for (; (X) < (Y); ++(X))
#define all(X) (X).begin(), (X).end()
#define rall(X) (X).rbegin(), (X).rend()

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
template <class T> ostream &operator<<(ostream &os, const vector<T> &t) {
  os << "{";
  rep(i, t.size()) { os << t[i] << ","; }
  os << "}" << endl;
  return os;
}
template <class S, class T>
ostream &operator<<(ostream &os, const pair<S, T> &t) {
  return os << "(" << t.first << "," << t.second << ")";
}
typedef vector<string> Graph;
int used[1123], v;
int dfs(Graph &g, int p) {
  if (used[p])
    return 0;
  used[p] = 1;
  int re = 1;
  rep(i, v) if (g[p][i] == 'Y') re += dfs(g, i);
  return re;
}

int memo[1124][2][2][2][2];

int solve(int n, int edge, int even, int rem, int to) {
  //  cout<<"("<<n<<","<<edge<<","<<even<<","<<rem<<","<<to<<")"<<endl;
  int re = 0;
  if (n == 2 && even == 0)
    return to == 1;
  if (n == 0 && even == 2)
    return to == 0;
  if (memo[n][edge][even][rem][to])
    return memo[n][edge][even][rem][to] - 1;
  if (even == 1 && to == 0) {
    re = 1;
  } else if (!rem) {
    re = 1 - solve(n - 2 + 2 * even, edge + even, 1 - even, 1, 1 - to);
  } else {
    if (even) {
      re |= 1 - solve(n, 1 - edge, 0, 1, 1 - to);
      if (rem % 2)
        re |= 1 - solve(n, 1 - edge, 1, 0, 1 - to);
    } else {
      re |= 1 - solve(n - 2, edge, 1, 1, 1 - to);
      if (rem % 2)
        re |= 1 - solve(n - 2, edge, 1, 0, 1 - to);
    }
  }
  memo[n][edge][even][rem][to] = re + 1;
  //  cout<<"("<<n<<","<<edge<<","<<even<<","<<rem<<","<<to<<"):"<<re<<endl;
  return re;
}

int main() {
  ios_base::sync_with_stdio(false);
  cout << fixed << setprecision(0);
  int i, j, k, e = 0;
  cin >> v;
  Graph strs(v);
  vector<int> ccs;
  rep(i, v) {
    cin >> strs[i];
    e += count(all(strs[i]), 'Y');
  }
  e /= 2;
  //  cout<<e<<endl;
  rep(i, v) if (!used[i]) ccs.pb(dfs(strs, i));
  int rem = 0;
  for (int cc : ccs)
    rem += (cc - 1) * cc / 2;
  rem -= e;
  //    cout<<ccs<<endl;
  if (v % 2) {
    cout << (e % 2 == v % 4 / 2 ? "Hanako" : "Taro") << endl;
  } else {
    int oc = 0, ec = ccs.size();
    rep(i, ccs.size()) oc += ccs[i] % 2;
    ec -= oc;
    //    cout<<ec<<","<<oc<<endl;
    if (ec == 0) {
      /*if(ccs.size()==2){
        cout<<"Hanako"<<endl;
        return 0;
        }*/
      //     cout<<"odd:"<<solve(oc,rem%2,0,rem>0,1)<<endl;
      //      cout<<"even:"<<solve(oc,rem%2,0,rem>0,0)<<endl;
      cout << (e % 2 == v / 2 % 2 && solve(oc, rem % 2, 0, rem > 0, 1) ||
                       e % 2 != v / 2 % 2 && solve(oc, rem % 2, 0, rem > 0, 0)
                   ? "Taro"
                   : "Hanako")
           << endl;
    } else if (ec == 1) {
      int odd = 0;
      cout << (solve(oc, rem % 2, 1, rem > 0, 1) || e % 2 != v / 2 % 2
                   ? "Taro"
                   : "Hanako")
           << endl;
    } else {
      cout << (e % 2 != v / 2 % 2 ? "Taro" : "Hanako") << endl;
    }
  }
  return 0;
}