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

#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <queue>
#include <tuple>
#include <vector>
using namespace std;
vector<vector<char>> S;
int n;
bool dp[13][160];
int LIM2 = 0;
int _size = 0;
int CC = 0;
vector<vector<char>> solve(vector<vector<char>> p, int x, int y, int r) {
  if (r == 1) {
    p[x][y]--;
    p[x + 1][y]--;
    p[x - 1][y]--;
    p[x][y - 1]--;
    p[x][y + 1]--;
  }
  if (r == 2) {
    for (int i = -1; i <= 1; i++)
      for (int j = -1; j <= 1; j++)
        p[x + i][y + j]--;
  }
  if (r == 3) {
    for (int i = -1; i <= 1; i++)
      for (int j = -1; j <= 1; j++)
        p[x + i][y + j]--;
    p[x + 2][y]--;
    p[x][y + 2]--;
    p[x - 2][y]--;
    p[x][y - 2]--;
  }
  return p;
}
bool isgood(int p) {
  if (p % 4 == 1 && p >= 5)
    return true;
  if (p % 4 == 2 && p >= 10)
    return true;
  if (p % 4 == 3 && p >= 15)
    return true;
  if (p % 4 == 0 && p >= 20)
    return true;
  return false;
}
bool hantei(vector<vector<char>> p) {
  for (int i = 0; i < 10; i++) {
    for (int j = 0; j < 10; j++) {
      if (p[i][j] < 0)
        return false;
    }
  }
  bool OKs[10][10];
  for (int i = 0; i < 100; i++)
    OKs[i / 10][i % 10] = false;
  for (int i = 1; i < 9; i++) {
    for (int j = 1; j < 9; j++) {
      if (p[i][j] == 0)
        continue;
      bool OK6 = false;
      if (p[i - 1][j] >= 1 && p[i + 1][j] >= 1 && p[i][j - 1] >= 1 &&
          p[i][j + 1] >= 1) {
        OK6 = true;
        OKs[i][j] = true;
        OKs[i - 1][j] = true;
        OKs[i][j - 1] = true;
        OKs[i][j + 1] = true;
        OKs[i + 1][j] = true;
      }
      if (OK6 == false)
        continue;
      bool OK4 = true;
      for (int k = -1; k <= 1; k++)
        for (int l = -1; l <= 1; l++)
          if (p[i + k][j + l] == 0)
            OK4 = false;
      if (OK4 == false)
        continue;
      for (int k = -1; k <= 1; k++)
        for (int l = -1; l <= 1; l++)
          OKs[i + k][j + l] = true;
    }
  }
  for (int i = 0; i <= 9; i++) {
    for (int j = 0; j <= 9; j++) {
      if (OKs[i][j] == false && p[i][j] >= 1)
        return false;
    }
  }
  queue<pair<int, int>> Q3;
  bool OK5[10][10];
  for (int i = 0; i < 100; i++)
    OK5[i / 10][i % 10] = false;
  if (rand() % 9 <= 1 && n == 12 && _size >= 1000)
    return false;
  return true;
}
vector<tuple<vector<vector<char>>, int, vector<tuple<char, char, char>>>> Vec;
void zen_shori() {
  int JJ = 165;
  if (LIM2 == 2)
    JJ = 27061;
  for (int i = 0; i < JJ; i++) {
    tuple<vector<vector<char>>, int, vector<tuple<char, char, char>>> ZZ;
    Vec.push_back(ZZ);
  }
  vector<vector<char>> ZERO;
  int LL = 0, RR = 0;
  vector<tuple<char, char, char>> ZERO3;
  for (int i = 0; i < 10; i++) {
    vector<char> ZERO5(10, 0);
    ZERO.push_back(ZERO5);
  }
  Vec[0] = make_tuple(ZERO, 0, ZERO3);
  RR++;
  while (LL < RR && RR < JJ) {
    vector<vector<char>> a1 = get<0>(Vec[LL]);
    int a2 = get<1>(Vec[LL]);
    vector<tuple<char, char, char>> a3 = get<2>(Vec[LL]);
    LL++;
    if (a2 == LIM2)
      continue;
    int L[4] = {0, 1, 1, 2}, R[4] = {9, 8, 8, 7}, P[4] = {0, 5, 9, 13};
    for (int i = 1; i <= 3; i++) {
      for (int j = L[i]; j <= R[i]; j++) {
        for (int k = L[i]; k <= R[i]; k++) {
          vector<vector<char>> a4 = solve(a1, j, k, i);
          vector<tuple<char, char, char>> a5 = a3;
          a5.push_back(make_tuple(j, k, i));
          if (RR < JJ) {
            Vec[RR] = make_tuple(a4, a2 + 1, a5);
            RR++;
          }
        }
      }
    }
  }
  for (int i = 0; i < Vec.size(); i++) {
    for (int j = 0; j < 10; j++) {
      for (int k = 0; k < 10; k++) {
        get<0>(Vec[i])[j][k] *= -1;
      }
    }
  }
  sort(Vec.begin(), Vec.end());
}
int main() {
  srand((unsigned)time(NULL));
  cin >> n;
  dp[0][0] = true;
  LIM2 = 2;
  for (int i = 0; i < 12; i++) {
    for (int j = 0; j < 160; j++) {
      if (dp[i][j] == false)
        continue;
      dp[i + 1][j + 5] = true;
      dp[i + 1][j + 9] = true;
      dp[i + 1][j + 13] = true;
    }
  }
  for (int i = 0; i < 10; i++) {
    vector<char> V(10, 0);
    S.push_back(V);
  }
  vector<vector<char>> START = S;
  int SUM = 0;
  for (int i = 0; i < 10; i++)
    for (int j = 0; j < 10; j++) {
      int SS;
      cin >> SS;
      S[i][j] = SS;
      SUM += S[i][j];
    }
  queue<tuple<int, vector<tuple<char, char, char>>, int>> Q;
  vector<tuple<char, char, char>> ZERO;
  Q.push(make_tuple(0, ZERO, SUM));
  zen_shori();
  CC = SUM;

  while (!Q.empty()) {
    vector<vector<char>> a1 = S;
    int a2 = get<0>(Q.front());
    vector<tuple<char, char, char>> a3 = get<1>(Q.front());
    int a4 = get<2>(Q.front());
    Q.pop();
    _size = Q.size();
    for (int i = 0; i < a3.size(); i++) {
      a1 = solve(a1, get<0>(a3[i]), get<1>(a3[i]), get<2>(a3[i]));
    }
    int L[4] = {0, 1, 1, 2}, R[4] = {9, 8, 8, 7}, P[4] = {0, 5, 9, 13};
    for (int i = 1; i <= 3; i++) {
      int rem1 = a4 - P[i], rem2 = n - (a2 + 1);
      bool OK = true;
      if (dp[rem2][rem1] == false)
        OK = false;
      if (OK == false)
        continue;
      int LIM = 0;
      if (a3.size() >= 1)
        LIM = get<0>(a3[a3.size() - 1]) * 100 + get<1>(a3[a3.size() - 1]) * 10 +
              get<2>(a3[a3.size() - 1]);
      for (int j = L[i]; j <= R[i]; j++) {
        for (int k = L[i]; k <= R[i]; k++) {
          int DD = j * 100 + k * 10 + i;
          if (DD < LIM)
            continue;
          vector<vector<char>> G = solve(a1, j, k, i);
          vector<tuple<char, char, char>> H = a3;
          if (hantei(G) == false)
            continue;
          H.push_back(make_tuple(j, k, i));
          if (G == START && a2 + 1 == n) {
            for (int j = 0; j < H.size(); j++) {
              cout << (int)get<1>(H[j]) << ' ' << (int)get<0>(H[j]) << ' '
                   << (int)get<2>(H[j]) << endl;
            }
            goto E;
          }
          if (a2 + 1 >= n - LIM2) {
            int P =
                lower_bound(Vec.begin(), Vec.end(), make_tuple(G, 0, ZERO)) -
                Vec.begin();
            if (P < Vec.size() && get<0>(Vec[P]) == G) {
              for (int j = 0; j < H.size(); j++) {
                cout << (int)get<1>(H[j]) << ' ' << (int)get<0>(H[j]) << ' '
                     << (int)get<2>(H[j]) << endl;
              }
              vector<tuple<char, char, char>> J = get<2>(Vec[P]);
              for (int j = 0; j < J.size(); j++) {
                cout << (int)get<1>(J[j]) << ' ' << (int)get<0>(J[j]) << ' '
                     << (int)get<2>(J[j]) << endl;
              }
              goto E;
            }
          }
          Q.push(make_tuple(a2 + 1, H, a4 - P[i]));
        }
      }
    }
  }
E:;
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <queue>
#include <tuple>
#include <vector>
using namespace std;
vector<vector<char>> S;
int n;
bool dp[13][160];
int LIM2 = 0;
int _size = 0;
int CC = 0;
vector<vector<char>> solve(vector<vector<char>> p, int x, int y, int r) {
  if (r == 1) {
    p[x][y]--;
    p[x + 1][y]--;
    p[x - 1][y]--;
    p[x][y - 1]--;
    p[x][y + 1]--;
  }
  if (r == 2) {
    for (int i = -1; i <= 1; i++)
      for (int j = -1; j <= 1; j++)
        p[x + i][y + j]--;
  }
  if (r == 3) {
    for (int i = -1; i <= 1; i++)
      for (int j = -1; j <= 1; j++)
        p[x + i][y + j]--;
    p[x + 2][y]--;
    p[x][y + 2]--;
    p[x - 2][y]--;
    p[x][y - 2]--;
  }
  return p;
}
bool isgood(int p) {
  if (p % 4 == 1 && p >= 5)
    return true;
  if (p % 4 == 2 && p >= 10)
    return true;
  if (p % 4 == 3 && p >= 15)
    return true;
  if (p % 4 == 0 && p >= 20)
    return true;
  return false;
}
bool hantei(vector<vector<char>> p) {
  for (int i = 0; i < 10; i++) {
    for (int j = 0; j < 10; j++) {
      if (p[i][j] < 0)
        return false;
    }
  }
  bool OKs[10][10];
  for (int i = 0; i < 100; i++)
    OKs[i / 10][i % 10] = false;
  for (int i = 1; i < 9; i++) {
    for (int j = 1; j < 9; j++) {
      if (p[i][j] == 0)
        continue;
      bool OK6 = false;
      if (p[i - 1][j] >= 1 && p[i + 1][j] >= 1 && p[i][j - 1] >= 1 &&
          p[i][j + 1] >= 1) {
        OK6 = true;
        OKs[i][j] = true;
        OKs[i - 1][j] = true;
        OKs[i][j - 1] = true;
        OKs[i][j + 1] = true;
        OKs[i + 1][j] = true;
      }
      if (OK6 == false)
        continue;
      bool OK4 = true;
      for (int k = -1; k <= 1; k++)
        for (int l = -1; l <= 1; l++)
          if (p[i + k][j + l] == 0)
            OK4 = false;
      if (OK4 == false)
        continue;
      for (int k = -1; k <= 1; k++)
        for (int l = -1; l <= 1; l++)
          OKs[i + k][j + l] = true;
    }
  }
  for (int i = 0; i <= 9; i++) {
    for (int j = 0; j <= 9; j++) {
      if (OKs[i][j] == false && p[i][j] >= 1)
        return false;
    }
  }
  queue<pair<int, int>> Q3;
  bool OK5[10][10];
  for (int i = 0; i < 100; i++)
    OK5[i / 10][i % 10] = false;
  if (rand() % 37 <= 7 && n == 12 && _size >= 1000)
    return false;
  return true;
}
vector<tuple<vector<vector<char>>, int, vector<tuple<char, char, char>>>> Vec;
void zen_shori() {
  int JJ = 165;
  if (LIM2 == 2)
    JJ = 27061;
  for (int i = 0; i < JJ; i++) {
    tuple<vector<vector<char>>, int, vector<tuple<char, char, char>>> ZZ;
    Vec.push_back(ZZ);
  }
  vector<vector<char>> ZERO;
  int LL = 0, RR = 0;
  vector<tuple<char, char, char>> ZERO3;
  for (int i = 0; i < 10; i++) {
    vector<char> ZERO5(10, 0);
    ZERO.push_back(ZERO5);
  }
  Vec[0] = make_tuple(ZERO, 0, ZERO3);
  RR++;
  while (LL < RR && RR < JJ) {
    vector<vector<char>> a1 = get<0>(Vec[LL]);
    int a2 = get<1>(Vec[LL]);
    vector<tuple<char, char, char>> a3 = get<2>(Vec[LL]);
    LL++;
    if (a2 == LIM2)
      continue;
    int L[4] = {0, 1, 1, 2}, R[4] = {9, 8, 8, 7}, P[4] = {0, 5, 9, 13};
    for (int i = 1; i <= 3; i++) {
      for (int j = L[i]; j <= R[i]; j++) {
        for (int k = L[i]; k <= R[i]; k++) {
          vector<vector<char>> a4 = solve(a1, j, k, i);
          vector<tuple<char, char, char>> a5 = a3;
          a5.push_back(make_tuple(j, k, i));
          if (RR < JJ) {
            Vec[RR] = make_tuple(a4, a2 + 1, a5);
            RR++;
          }
        }
      }
    }
  }
  for (int i = 0; i < Vec.size(); i++) {
    for (int j = 0; j < 10; j++) {
      for (int k = 0; k < 10; k++) {
        get<0>(Vec[i])[j][k] *= -1;
      }
    }
  }
  sort(Vec.begin(), Vec.end());
}
int main() {
  srand((unsigned)time(NULL));
  cin >> n;
  dp[0][0] = true;
  LIM2 = 2;
  for (int i = 0; i < 12; i++) {
    for (int j = 0; j < 160; j++) {
      if (dp[i][j] == false)
        continue;
      dp[i + 1][j + 5] = true;
      dp[i + 1][j + 9] = true;
      dp[i + 1][j + 13] = true;
    }
  }
  for (int i = 0; i < 10; i++) {
    vector<char> V(10, 0);
    S.push_back(V);
  }
  vector<vector<char>> START = S;
  int SUM = 0;
  for (int i = 0; i < 10; i++)
    for (int j = 0; j < 10; j++) {
      int SS;
      cin >> SS;
      S[i][j] = SS;
      SUM += S[i][j];
    }
  queue<tuple<int, vector<tuple<char, char, char>>, int>> Q;
  vector<tuple<char, char, char>> ZERO;
  Q.push(make_tuple(0, ZERO, SUM));
  zen_shori();
  CC = SUM;

  while (!Q.empty()) {
    vector<vector<char>> a1 = S;
    int a2 = get<0>(Q.front());
    vector<tuple<char, char, char>> a3 = get<1>(Q.front());
    int a4 = get<2>(Q.front());
    Q.pop();
    _size = Q.size();
    for (int i = 0; i < a3.size(); i++) {
      a1 = solve(a1, get<0>(a3[i]), get<1>(a3[i]), get<2>(a3[i]));
    }
    int L[4] = {0, 1, 1, 2}, R[4] = {9, 8, 8, 7}, P[4] = {0, 5, 9, 13};
    for (int i = 1; i <= 3; i++) {
      int rem1 = a4 - P[i], rem2 = n - (a2 + 1);
      bool OK = true;
      if (dp[rem2][rem1] == false)
        OK = false;
      if (OK == false)
        continue;
      int LIM = 0;
      if (a3.size() >= 1)
        LIM = get<0>(a3[a3.size() - 1]) * 100 + get<1>(a3[a3.size() - 1]) * 10 +
              get<2>(a3[a3.size() - 1]);
      for (int j = L[i]; j <= R[i]; j++) {
        for (int k = L[i]; k <= R[i]; k++) {
          int DD = j * 100 + k * 10 + i;
          if (DD < LIM)
            continue;
          vector<vector<char>> G = solve(a1, j, k, i);
          vector<tuple<char, char, char>> H = a3;
          if (hantei(G) == false)
            continue;
          H.push_back(make_tuple(j, k, i));
          if (G == START && a2 + 1 == n) {
            for (int j = 0; j < H.size(); j++) {
              cout << (int)get<1>(H[j]) << ' ' << (int)get<0>(H[j]) << ' '
                   << (int)get<2>(H[j]) << endl;
            }
            goto E;
          }
          if (a2 + 1 >= n - LIM2) {
            int P =
                lower_bound(Vec.begin(), Vec.end(), make_tuple(G, 0, ZERO)) -
                Vec.begin();
            if (P < Vec.size() && get<0>(Vec[P]) == G) {
              for (int j = 0; j < H.size(); j++) {
                cout << (int)get<1>(H[j]) << ' ' << (int)get<0>(H[j]) << ' '
                     << (int)get<2>(H[j]) << endl;
              }
              vector<tuple<char, char, char>> J = get<2>(Vec[P]);
              for (int j = 0; j < J.size(); j++) {
                cout << (int)get<1>(J[j]) << ' ' << (int)get<0>(J[j]) << ' '
                     << (int)get<2>(J[j]) << endl;
              }
              goto E;
            }
          }
          Q.push(make_tuple(a2 + 1, H, a4 - P[i]));
        }
      }
    }
  }
E:;
  return 0;
}