Problem p01397 (C++) — buggy submission, verdict: Runtime Error

#include <cstdio>

#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

typedef long long ll;

const ll M = 1000000007;
const int dx[] = {2, 1, -1, -2, -2, -1, 1, 2},
          dy[] = {-1, -2, -2, -1, 1, 2, 2, 1};

int h, w, B[50][16];

int cnt[50][16]; // 攻撃されうる回数

ll dfs(int i, int j, int parity) {
  if (i == h)
    return 1;
  if (j == w)
    return dfs(i + 1, 0, parity);

  if ((i + j) % 2 != parity)
    return dfs(i, j + 1, parity); // 黒マス or 白マスのみ見る

  // マス (i, j) での値を mod 3 で 0 にできなければ探索打ち切り ( (i, j)
  // を攻撃するマスがないかもしれないので必要 )
  if (cnt[i][j] == 0 && B[i][j] % 3 != 0 || cnt[i][j] == 1 && B[i][j] % 3 == 1)
    return 0;

  ll res = 0;
  // マス (i, j) にナイトを置かない
  rep(k, 8) {
    int y = i + dy[k], x = j + dx[k];
    if (0 <= y && y < h && 0 <= x && x < w)
      cnt[y][x]--;
  }
  bool ok = true;
  rep(k, 8) {
    int y = i + dy[k], x = j + dx[k];
    if (0 <= y && y < h && 0 <= x && x < w) {
      if (cnt[y][x] == 0 && B[y][x] % 3 != 0 ||
          cnt[y][x] == 1 && B[y][x] % 3 == 1)
        ok = false;
    }
  }
  if (ok)
    res += dfs(i, j + 1, parity);

  // マス (i, j) にナイトを置く
  rep(k, 8) {
    int y = i + dy[k], x = j + dx[k];
    if (0 <= y && y < h && 0 <= x && x < w)
      B[y][x]++;
  }
  ok = true;
  rep(k, 8) {
    int y = i + dy[k], x = j + dx[k];
    if (0 <= y && y < h && 0 <= x && x < w) {
      if (cnt[y][x] == 0 && B[y][x] % 3 != 0 ||
          cnt[y][x] == 1 && B[y][x] % 3 == 1)
        ok = false;
    }
  }
  if (ok)
    res += dfs(i, j + 1, parity);

  rep(k, 8) {
    int y = i + dy[k], x = j + dx[k];
    if (0 <= y && y < h && 0 <= x && x < w)
      cnt[y][x]++, B[y][x]--;
  }

  return res;
}

int main() {
  scanf("%d%d", &h, &w);
  rep(i, h) rep(j, w) scanf("%d", B[i] + j);

  rep(i, h) rep(j, w) rep(k, 8) {
    int y = i + dy[k], x = j + dx[k];
    if (0 <= y && y < h && 0 <= x && x < w)
      cnt[y][x]++;
  }

  ll ans;
  if (h == 1 || w == 1) { // コーナーケース
    bool ok = true;
    rep(i, h) rep(j, w) if (B[i][j] != 0) ok = false;
    if (ok) {
      ans = 1;
      rep(i, h * w) ans = 2 * ans % M;
    } else
      ans = 0;
  } else {
    ans = dfs(0, 0, 0) * dfs(0, 1, 1) % M;
  }
  printf("%lld\\n", ans);

  return 0;
}

Error: 0

Fixed submission:

#include <cstdio>

#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;

typedef long long ll;

const ll M = 1000000007;
const int dx[] = {2, 1, -1, -2, -2, -1, 1, 2},
          dy[] = {-1, -2, -2, -1, 1, 2, 2, 1};

int h, w, B[50][16];

int cnt[16][50]; // 攻撃されうる回数

ll dfs(int i, int j, int parity) {
  if (i == h)
    return 1;
  if (j == w)
    return dfs(i + 1, 0, parity);

  if ((i + j) % 2 != parity)
    return dfs(i, j + 1, parity); // 黒マス or 白マスのみ見る

  ll res = 0;
  // マス (i, j) にナイトを置く
  rep(k, 8) {
    int y = i + dy[k], x = j + dx[k];
    if (0 <= y && y < h && 0 <= x && x < w)
      cnt[y][x]--;
  }
  bool ok = true;
  rep(k, 8) {
    int y = i + dy[k], x = j + dx[k];
    if (0 <= y && y < h && 0 <= x && x < w) {
      if (cnt[y][x] == 0 && B[y][x] % 3 != 0 ||
          cnt[y][x] == 1 && B[y][x] % 3 == 1)
        ok = false;
    }
  }
  if (ok)
    res += dfs(i, j + 1, parity);

  // マス (i, j) にナイトを置かない
  rep(k, 8) {
    int y = i + dy[k], x = j + dx[k];
    if (0 <= y && y < h && 0 <= x && x < w)
      B[y][x]++;
  }
  ok = true;
  rep(k, 8) {
    int y = i + dy[k], x = j + dx[k];
    if (0 <= y && y < h && 0 <= x && x < w) {
      if (cnt[y][x] == 0 && B[y][x] % 3 != 0 ||
          cnt[y][x] == 1 && B[y][x] % 3 == 1)
        ok = false;
    }
  }
  if (ok)
    res += dfs(i, j + 1, parity);

  rep(k, 8) {
    int y = i + dy[k], x = j + dx[k];
    if (0 <= y && y < h && 0 <= x && x < w)
      cnt[y][x]++, B[y][x]--;
  }

  return res;
}

int main() {
  scanf("%d%d", &h, &w);
  rep(i, h) rep(j, w) scanf("%d", B[i] + j);

  rep(i, h) rep(j, w) cnt[i][j] = 0;
  rep(i, h) rep(j, w) rep(k, 8) {
    int y = i + dy[k], x = j + dx[k];
    if (0 <= y && y < h && 0 <= x && x < w)
      cnt[y][x]++;
  }

  ll ans;
  if (h == 1 || w == 1) {
    ans = 1;
    rep(i, h * w) ans = 2 * ans % M;
  } else
    ans = dfs(0, 0, 0) * dfs(0, 1, 1) % M;
  printf("%lld\\n", ans);

  return 0;
}