Problem p00620 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <iostream>

using namespace std;

#define MAX 16
#define INV -128

const int di[] = {-1, 0, 1, 0};
const int dj[] = {0, 1, 0, -1};

bool dfs(int si, int sj, int n, int map[][MAX], bool vis[][MAX], int now,
         int left) {

  // cout << si << ' ' <<  sj << endl;

  // if( now > 0 ) return false;

  if (now == 0) {
    --left;
    if (left == 0) {
      for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
          if (!vis[i + 1][j + 1])
            return false;
        }
      }
      return true;
    } else {
      for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
          if (map[i + 1][j + 1] < 0 && !vis[i + 1][j + 1]) {
            vis[i + 1][j + 1] = true;
            if (dfs(i + 1, j + 1, n, map, vis, map[i + 1][j + 1], left))
              return true;
            vis[i + 1][j + 1] = false;
            return false;
          }
        }
      }
    }
  } else {
    for (int k = 0; k < sizeof(di) / sizeof(*di); ++k) {
      int ti = si + di[k];
      int tj = sj + dj[k];
      if (map[ti][tj] > 0 && map[ti][tj] != INV && !vis[ti][tj] &&
          now + map[ti][tj] <= 0) {
        vis[ti][tj] = true;
        if (dfs(ti, tj, n, map, vis, now + map[ti][tj], left))
          return true;
        vis[ti][tj] = false;
      }
    }
  }
  return false;
}

int main() {
  while (true) {
    int n;
    int left = 0;
    bool ans = false;
    int map[MAX][MAX];
    bool vis[MAX][MAX];
    cin >> n;
    if (n == 0)
      break;
    for (int i = 0; i < MAX; ++i) {
      for (int j = 0; j < MAX; ++j) {
        map[i][j] = INV;
        vis[i][j] = false;
      }
    }
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < n; ++j) {
        cin >> map[i + 1][j + 1];
        if (map[i + 1][j + 1] < 0)
          ++left;
      }
    }

    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < n; ++j) {
        if (map[i + 1][j + 1] < 0) {
          vis[i + 1][j + 1] = true;
          if (dfs(i + 1, j + 1, n, map, vis, map[i + 1][j + 1], left))
            ans = true;
          else
            ans = false;
          goto END;
        }
      }
    }

  END:;
    if (ans) {
      cout << "YES" << endl;
    } else {
      cout << "NO" << endl;
    }
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <iostream>

using namespace std;

#define MAX 16
#define INV -128

const int di[] = {-1, 0, 1, 0};
const int dj[] = {0, 1, 0, -1};

bool dfs(int si, int sj, int n, int map[][MAX], bool vis[][MAX], int now,
         int left) {

  // cout << si << ' ' <<  sj << endl;

  if (now == 0) {
    --left;
    if (left == 0) {
      for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
          if (!vis[i + 1][j + 1])
            return false;
        }
      }
      return true;
    } else {
      for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
          if (map[i + 1][j + 1] < 0 && !vis[i + 1][j + 1]) {
            vis[i + 1][j + 1] = true;
            if (dfs(i + 1, j + 1, n, map, vis, -map[i + 1][j + 1], left))
              return true;
            vis[i + 1][j + 1] = false;
          }
        }
      }
    }
  } else {
    for (int k = 0; k < sizeof(di) / sizeof(*di); ++k) {
      int ti = si + di[k];
      int tj = sj + dj[k];
      if (map[ti][tj] > 0 && map[ti][tj] != INV && !vis[ti][tj]) {
        vis[ti][tj] = true;
        if (dfs(ti, tj, n, map, vis, now - map[ti][tj], left))
          return true;
        vis[ti][tj] = false;
      }
    }
  }
  return false;
}

int main() {
  while (true) {
    int n;
    int left = 0;
    bool ans = false;
    int map[MAX][MAX];
    bool vis[MAX][MAX];
    cin >> n;
    if (n == 0)
      break;
    for (int i = 0; i < MAX; ++i) {
      for (int j = 0; j < MAX; ++j) {
        map[i][j] = INV;
        vis[i][j] = false;
      }
    }
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < n; ++j) {
        cin >> map[i + 1][j + 1];
        if (map[i + 1][j + 1] < 0)
          ++left;
      }
    }

    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < n; ++j) {
        if (map[i + 1][j + 1] < 0) {
          vis[i + 1][j + 1] = true;
          if (dfs(i + 1, j + 1, n, map, vis, -map[i + 1][j + 1], left))
            ans = true;
          else
            ans = false;
          goto END;
        }
      }
    }

  END:;
    if (ans) {
      cout << "YES" << endl;
    } else {
      cout << "NO" << endl;
    }
  }
  return 0;
}