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

#include <algorithm>
#include <iostream>
using namespace std;

const int dx[] = {0, 1, 0, -1, 0, 1, -1, -1, 1, 2, 0, -2, 0};
const int dy[] = {0, 0, 1, 0, -1, 1, 1, -1, -1, 0, 2, 0, -2};
const int num[3] = {5, 9, 13};
const int wx[3] = {0, 1, 0};
const int wy[3] = {1, 1, 2};
const int R = 10;
const int MAXN = 12;
const int MAXSUM = 13 * 12 + 1;

int N;
int G[R][R];
int sum;
int X[MAXN], Y[MAXN], S[MAXN];
bool can[MAXSUM];

bool draw(int x, int y, int s, int c) {
  for (int i = 0; i < num[s]; ++i) {
    int nx = x + dx[i];
    int ny = y + dy[i];
    if (nx < 0 || nx >= R)
      return false;
    if (ny < 0 || ny >= R)
      return false;
    if (G[ny][nx] + c < 0)
      return false;
  }
  for (int i = 0; i < num[s]; ++i) {
    int nx = x + dx[i];
    int ny = y + dy[i];
    G[ny][nx] += c;
  }
  return true;
}

bool rec(int k, int m, int x, int y) {
  if (k == N) {
    if (m == sum) {
      for (int i = 0; i < N; ++i) {
        cout << X[i] << " " << Y[i] << " " << S[i] << endl;
      }
      return true;
    } else {
      return false;
    }
  }

  if (!can[sum - m])
    return false;
  if (m + (N - k) * num[0] > sum)
    return false;

  for (; y < R; ++y) {
    for (x %= R; x < R; ++x) {
      if (G[y][x] != 0) {
        for (int s = 0; s < 3; ++s) {
          int px = x + wx[s];
          int py = y + wy[s];
          if (draw(px, py, s, -1)) {
            X[k] = px;
            Y[k] = py;
            S[k] = s + 1;
            if (rec(k + 1, m + num[s], x, y))
              return true;
            draw(px, py, s, 1);
          }
        }
        return false;
      }
    }
  }
  return false;
}

int main() {
  can[0] = true;
  for (int i = 0; i < MAXSUM; ++i) {
    if (!can[i])
      continue;
    for (int j = 0; j < 3; ++j) {
      if (i + num[j] >= MAXSUM)
        break;
      can[i + num[j]] = true;
    }
  }

  cin >> N;
  for (int i = 0; i < R; ++i) {
    for (int j = 0; j < R; ++j) {
      cin >> G[i][j];
      sum += G[i][j];
    }
  }
  rec(0, 0, 0, 0);
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>
using namespace std;

const int dx[] = {0, 1, 0, -1, 0, 1, -1, -1, 1, 2, 0, -2, 0};
const int dy[] = {0, 0, 1, 0, -1, 1, 1, -1, -1, 0, 2, 0, -2};
const int num[3] = {5, 9, 13};
const int R = 10;
const int MAXN = 12;
const int MAXSUM = 13 * 12 + 1;

int N;
int G[R][R];
int sum;
int X[MAXN], Y[MAXN], S[MAXN];
bool can[MAXSUM];

int draw(int x, int y, int s, int c) {
  for (int i = 0; i < num[s]; ++i) {
    int nx = x + dx[i];
    int ny = y + dy[i];
    if (nx < 0 || nx >= R)
      return false;
    if (ny < 0 || ny >= R)
      return false;
    if (G[ny][nx] + c < 0)
      return false;
  }
  for (int i = 0; i < num[s]; ++i) {
    int nx = x + dx[i];
    int ny = y + dy[i];
    G[ny][nx] += c;
  }
  return num[s];
}

bool rec(int k, int m, int x, int y, int s) {
  if (k == N) {
    if (m == sum) {
      for (int i = 0; i < N; ++i) {
        cout << X[i] << " " << Y[i] << " " << S[i] << endl;
      }
      return true;
    } else {
      return false;
    }
  }
  if (!can[sum - m])
    return false;
  if (m + (N - k) * num[0] > sum)
    return false;

  for (; y < R; ++y) {
    for (; x < R; ++x) {
      if (G[y][x] == 0)
        continue;
      for (; s < 3; ++s) {
        int tmp;
        if (tmp = draw(x, y, s, -1)) {
          X[k] = x;
          Y[k] = y;
          S[k] = s + 1;
          if (rec(k + 1, m + tmp, x, y, s))
            return true;
          draw(x, y, s, 1);
        }
      }
      s = 0;
    }
    x = 0;
  }
  return false;
}

int main() {
  can[0] = true;
  for (int i = 0; i < MAXSUM; ++i) {
    if (!can[i])
      continue;
    for (int j = 0; j < 3; ++j) {
      if (i + num[j] >= MAXSUM)
        break;
      can[i + num[j]] = true;
    }
  }

  cin >> N;
  for (int i = 0; i < R; ++i) {
    for (int j = 0; j < R; ++j) {
      cin >> G[i][j];
      sum += G[i][j];
    }
  }
  rec(0, 0, 0, 0, 0);
  return 0;
}