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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
// cin.sync_with_stdio(false);
// streambuf
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
using pll = pair<ll, ll>;
typedef pair<double, double> pdd;
using vi = vector<int>;
using vll = vector<ll>;
using vpii = vector<pii>;
using ti3 = tuple<int, int, int>;
template <class T, class T2> using umap = unordered_map<T, T2>;
template <class T> using uset = unordered_set<T>;
#define ALL(a) a.begin(), a.end()
#define rep(i, a) for (int i = 0; i < a; i++)
#define rep1(i, a) for (int i = 1; i <= a; i++)
#pragma warning(disable : 4996)
#define INF 1000000000000000.0
int n;
vector<vector<vector<vi>>> oti(n, vector<vector<vi>>(2, vector<vi>(2, vi(2))));
int otosu(vector<vector<vi>> &buf) {
  int ans = 0;
  bool f = 1;
  int cnt = 1;
  vector<int> fl(3);
  while (f) {
    f = 0;
    fill(ALL(fl), 1);
    rep(j, 16) {
      rep(k, 2) rep(l, 2) {
        if (j == 0 ||
            buf[j - 1][k][l] != 0 && buf[j][k][l] != buf[j - 1][k][l]) {
          if (buf[j][k][l] > 1)
            fl[buf[j][k][l] - 2] = 0;
        } else if (buf[j][k][l] > 1)
          fl[buf[j][k][l] - 2] |= 2;
      }
    }
    if (fl[0] == 3)
      fl[1] = fl[2] = 0, f = 1;
    else
      fl[0] = 0;
    if (fl[1] == 3)
      fl[2] = 0, f = 1;
    else
      fl[1] = 0;
    if (fl[2] == 3)
      f = 1;
    else
      fl[2] = 0;
    rep(i, 16) rep(j, 2) rep(k, 2) {
      if (buf[i][j][k] > 1 && fl[buf[i][j][k] - 2])
        swap(buf[i - 1][j][k], buf[i][j][k]);
    }
  }
  f = 1;
  while (f) {
    f = 0;
    rep(i, 16) {
      int f2 = 1;
      rep(j, 2) rep(k, 2) {
        if (!buf[i][j][k])
          f2 = 0;
      }
      if (f2) {
        for (; i < 15; i++) {
          rep(j, 2) rep(k, 2) { buf[i][j][k] = buf[i + 1][j][k]; }
        }
        rep(j, 2) rep(k, 2) { buf[15][j][k] = 0; }
        f = 1;
        ans++;
        break;
      }
    }
  }
  return ans;
}
int dfs(vector<vector<vi>> &buf, int a) {
  if (a == n)
    return 0;
  int ans = 0;
  rep(i, 3) rep(j, 3) {
    auto buf1 = buf;
    int offset;
    rep(k, 2) rep(l, 2) rep(m, 2) {
      if (oti[a][k][l][m]) {
        if (l + i > 2 || j + m > 2 || l + i == 0 || j + m == 0)
          goto x;
        buf1[10 + 2 * a + k][l + i - 1][j + m - 1] = oti[a][k][l][m];
      }
    }
    offset = otosu(buf1);
    rep(i, 16) rep(j, 2) rep(k, 2) buf1[i][j][k] = buf1[i][j][k] ? 1 : 0;
    ans = max(ans, dfs(buf1, a + 1) + offset);
  x:;
  }
  return ans;
}
int main() {
  int h;
  while (cin >> h >> n, h) {
    vector<vector<vi>> buf(16, vector<vi>(2, vi(2)));
    oti.clear();
    oti.resize(n, vector<vector<vi>>(2, vector<vi>(2, vi(2))));
    rep(i, h) {
      rep(j, 2) rep(k, 2) {
        char a;
        cin >> a;
        buf[i][j][k] = a == '.' ? 0 : 1;
      }
    }
    rep(i, n) {
      rep(j, 2) rep(k, 2) rep(l, 2) {
        char a;
        cin >> a;
        oti[i][j][k][l] = a == '.' ? 0 : i + 2;
      }
    }
    cout << dfs(buf, 0) << endl;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
// cin.sync_with_stdio(false);
// streambuf
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
using pll = pair<ll, ll>;
typedef pair<double, double> pdd;
using vi = vector<int>;
using vll = vector<ll>;
using vpii = vector<pii>;
using ti3 = tuple<int, int, int>;
template <class T, class T2> using umap = unordered_map<T, T2>;
template <class T> using uset = unordered_set<T>;
#define ALL(a) a.begin(), a.end()
#define rep(i, a) for (int i = 0; i < a; i++)
#define rep1(i, a) for (int i = 1; i <= a; i++)
#pragma warning(disable : 4996)
#define INF 1000000000000000.0
int n;
vector<vector<vector<vi>>> oti(n, vector<vector<vi>>(2, vector<vi>(2, vi(2))));
int otosu(vector<vector<vi>> &buf) {
  int ans = 0;
  bool f = 1;
  int cnt = 1;
  vector<int> fl(3);
  while (f) {
    f = 0;
    fill(ALL(fl), 1);
    rep(j, 16) {
      rep(k, 2) rep(l, 2) {
        if (j == 0 ||
            buf[j - 1][k][l] != 0 && buf[j][k][l] != buf[j - 1][k][l]) {
          if (buf[j][k][l] > 1)
            fl[buf[j][k][l] - 2] = 0;
        } else if (buf[j][k][l] > 1)
          fl[buf[j][k][l] - 2] |= 2;
      }
    }
    if (fl[0] == 3)
      fl[1] = fl[2] = 0, f = 1;
    else
      fl[0] = 0;
    if (fl[1] == 3)
      fl[2] = 0, f = 1;
    else
      fl[1] = 0;
    if (fl[2] == 3)
      f = 1;
    else
      fl[2] = 0;
    rep(i, 16) rep(j, 2) rep(k, 2) {
      if (buf[i][j][k] > 1 && fl[buf[i][j][k] - 2])
        swap(buf[i - 1][j][k], buf[i][j][k]);
    }
  }
  f = 1;
  while (f) {
    rep(i, 16) {
      int f2 = 1;
      rep(j, 2) rep(k, 2) {
        if (!buf[i][j][k])
          f2 = 0;
      }
      if (f2) {
        for (; i < 15; i++) {
          rep(j, 2) rep(k, 2) { buf[i][j][k] = buf[i + 1][j][k]; }
        }
        rep(j, 2) rep(k, 2) { buf[15][j][k] = 0; }
        f = 1;
        ans++;
        break;
      }
    }
  }
  return ans;
}
int dfs(vector<vector<vi>> &buf, int a) {
  if (a == n)
    return 0;
  int ans = 0;
  rep(i, 3) rep(j, 3) {
    auto buf1 = buf;
    int offset;
    rep(k, 2) rep(l, 2) rep(m, 2) {
      if (oti[a][k][l][m]) {
        if (l + i > 2 || j + m > 2 || l + i == 0 || j + m == 0)
          goto x;
        buf1[10 + 2 * a + k][l + i - 1][j + m - 1] = oti[a][k][l][m];
      }
    }
    offset = otosu(buf1);
    rep(i, 16) rep(j, 2) rep(k, 2) buf[i][j][k] = (bool)buf[i][j][k];
    ans = max(ans, dfs(buf1, a + 1) + offset);
  x:;
  }
  return ans;
}
int main() {
  int h;
  while (cin >> h >> n, h) {
    vector<vector<vi>> buf(16, vector<vi>(2, vi(2)));
    oti.clear();
    oti.resize(n, vector<vector<vi>>(2, vector<vi>(2, vi(2))));
    rep(i, h) {
      rep(j, 2) rep(k, 2) {
        char a;
        cin >> a;
        buf[i][j][k] = a == '.' ? 0 : 1;
      }
    }
    rep(i, n) {
      rep(j, 2) rep(k, 2) rep(l, 2) {
        char a;
        cin >> a;
        oti[i][j][k][l] = a == '.' ? 0 : i + 2;
      }
    }
    cout << dfs(buf, 0) << endl;
  }
}