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

#include <iomanip>
#include <iostream>
#include <vector>
using namespace std;

struct Drop {
  Drop(int _x, int _y, int _s) : x(_x), y(_y), size(_s) {}
  int x;
  int y;
  int size;
};

const int DROP_POS_NUM = 13;

int offset[DROP_POS_NUM][2] = {{0, 0},  {0, -1}, {1, 0},  {0, 1},   {-1, 0},
                               {1, -1}, {1, 1},  {-1, 1}, {-1, -1}, {0, -2},
                               {2, 0},  {0, 2},  {-2, 0}};

const int drop_size[] = {0, 5, 9, 13};

const int drops[] = {
    0,
    (1 << drop_size[1]) - 1,
    (1 << drop_size[2]) - 1,
    (1 << drop_size[3]) - 1,
};

bool solve(vector<vector<int>> &field, vector<vector<int>> &memo,
           vector<Drop> &ans, int r, int pos, int sum) {
  if (r == 0 && sum == 0) {
    return true;
  }

  for (int p = pos; p < 10 * 10; ++p) {
    int x = p % 10 + 2;
    int y = p / 10 + 2;
    if (field[y][x] == 0)
      continue;
    for (int k = DROP_POS_NUM - 1; k > 0; --k) {
      int dx = x + offset[k][0];
      int dy = y + offset[k][1];
      for (int s = 3; s > 0; --s) {
        if ((memo[dy][dx] & drops[s]) == drops[s]) {
          vector<vector<int>> f = field;
          vector<vector<int>> m = memo;
          for (int l = 0; l < drop_size[s]; ++l) {
            int fx = dx + offset[l][0];
            int fy = dy + offset[l][1];
            f[fy][fx]--;
            if (f[fy][fx] == 0) {
              for (int t = 0; t < DROP_POS_NUM; ++t) {
                int ex = fx + offset[t][0];
                int ey = fy + offset[t][1];
                int bit = 1;
                if (t != 0) {
                  int shift = t + ((t + 3) % 4 < 2 ? 2 : -2);
                  bit <<= shift;
                }
                m[ey][ex] &= ~bit;
              }
            }
          }
          if (solve(f, m, ans, r - 1, pos, sum - drop_size[s])) {
            ans.push_back(Drop(dx - 2, dy - 2, s));
            return true;
          }
        }
      }
    }
    return false;
  }

  return false;
}

int main() {
  int n;
  while (cin >> n) {
    vector<vector<int>> field(10 + 4, vector<int>(10 + 4, 0));
    int sum = 0;
    for (int i = 0; i < 10; ++i) {
      for (int j = 0; j < 10; ++j) {
        int a;
        cin >> a;
        field[i + 2][j + 2] = a;
        sum += a;
      }
    }

    vector<vector<int>> memo(10 + 4, vector<int>(10 + 4, 0));
    for (int i = 2; i < 10 + 2; ++i) {
      for (int j = 2; j < 10 + 2; ++j) {
        int bits = 0;
        for (int k = 0; k < DROP_POS_NUM; ++k) {
          int x = j + offset[k][0];
          int y = i + offset[k][1];
          if (field[y][x] > 0) {
            bits |= (1 << k);
          }
        }
        memo[i][j] = bits;
      }
    }

    vector<Drop> ans;
    solve(field, memo, ans, n, 0, sum);

    for (int i = 0; i < n; ++i) {
      cout << ans[i].x << " " << ans[i].y << " " << ans[i].size << endl;
    }
  }
  return 0;
}

Error: TLE

Fixed submission:

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

int pattern[4][5][5] = {{},
                        {{0, 0, 0, 0, 0},
                         {0, 0, 1, 0, 0},
                         {0, 1, 1, 1, 0},
                         {0, 0, 1, 0, 0},
                         {0, 0, 0, 0, 0}},
                        {{0, 0, 0, 0, 0},
                         {0, 1, 1, 1, 0},
                         {0, 1, 1, 1, 0},
                         {0, 1, 1, 1, 0},
                         {0, 0, 0, 0, 0}},
                        {{0, 0, 1, 0, 0},
                         {0, 1, 1, 1, 0},
                         {1, 1, 1, 1, 1},
                         {0, 1, 1, 1, 0},
                         {0, 0, 1, 0, 0}}};

struct Drop {
  Drop() : size(1), x(0), y(0) {}
  Drop(int _s, int _x, int _y) : size(_s), x(_x), y(_y) {}
  int size, x, y;
};

bool solve2(int p, vector<vector<int>> &map, vector<Drop> &ans) {
  if (p == ans.size()) {
    return true;
  }

  int b, e, d, s = ans[p].size;
  switch (s) {
  case 1:
  case 2:
    b = 1, e = 9, d = 1;
    break;
  case 3:
    b = 2, e = 8, d = 2;
    break;
  }
  for (int i = b; i < e; ++i) {
    bool ret = true;
    vector<vector<int>> m = map;
    for (int y = -d; y <= d; ++y) {
      for (int x = -d; x <= d; ++x) {
        int u = ans[p].x + x, v = i + y;
        if (pattern[s][2 + y][2 + x] > 0) {
          if (m[v][u] <= 0) {
            ret = false;
            break;
          }
          m[v][u]--;
        }
      }
      if (!ret)
        break;
    }
    if (!ret)
      continue;
    ret = solve2(p + 1, m, ans);
    if (ret) {
      ans[p].y = i;
      return true;
    }
  }

  return false;
}

bool solve(int n, int sum, vector<vector<int>> &map, vector<int> &col,
           vector<Drop> &ans) {
  static int size[3] = {2, 3, 1};
  if (sum < 0 || (n == 0 && sum != 0)) {
    return false;
  }
  if (n == 0) {
    return solve2(0, map, ans);
  }
  bool ret = false;
  for (int i = 0; i < 3; ++i) {
    switch (size[i]) {
    case 3:
      for (int j = 2; j < 8; ++j) {
        vector<int> c = col;
        if (c[j - 2] >= 1 && c[j - 1] >= 3 && c[j] >= 5 && c[j + 1] >= 3 &&
            c[j + 2] >= 1) {
          ans.push_back(Drop(size[i], j, -1));
          c[j - 2] -= 1, c[j - 1] -= 3, c[j] -= 5, c[j + 1] -= 3, c[j + 2] -= 1;
          ret = solve(n - 1, sum - 13, map, c, ans);
          if (ret)
            break;
          ans.pop_back();
        }
      }
      break;
    case 2:
      for (int j = 1; j < 9; ++j) {
        vector<int> c = col;
        if (c[j - 1] >= 3 && c[j] >= 3 && c[j + 1] >= 3) {
          c[j - 1] -= 3, c[j] -= 3, c[j + 1] -= 3;
          ans.push_back(Drop(size[i], j, -1));
          ret = solve(n - 1, sum - 9, map, c, ans);
          if (ret)
            break;
          ans.pop_back();
        }
      }
      break;
    case 1:
      for (int j = 1; j < 9; ++j) {
        vector<int> c = col;
        if (c[j - 1] >= 1 && c[j] >= 3 && c[j + 1] >= 1) {
          c[j - 1] -= 1, c[j] -= 3, c[j + 1] -= 1;
          ans.push_back(Drop(size[i], j, -1));
          ret = solve(n - 1, sum - 5, map, c, ans);
          if (ret)
            break;
          ans.pop_back();
        }
      }
      break;
    }
    if (ret)
      return true;
  }
  return false;
}

int main() {
  int n;
  while (cin >> n) {
    vector<vector<int>> map(10, vector<int>(10, 0));
    vector<int> col(10, 0);
    int sum = 0;
    for (int i = 0; i < 10; ++i) {
      for (int j = 0; j < 10; ++j) {
        cin >> map[i][j];
        sum += map[i][j];
        col[j] += map[i][j];
      }
    }
    vector<Drop> ans;
    solve(n, sum, map, col, ans);
    for (int i = 0; i < (int)ans.size(); ++i) {
      cout << ans[i].x << " " << ans[i].y << " " << ans[i].size << endl;
    }
  }
  return 0;
}