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

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
using namespace std;

#define REP(i, n) for (int i = 0; i < (int)n; ++i)
#define FOR(i, c)                                                              \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define ALL(c) (c).begin(), (c).end()
const int INF = 1 << 29;
typedef pair<int, int> pii;

struct P {
  int d;
  int y1, x1;
  P(int d, int y1, int x1) : d(d), y1(y1), x1(x1) {}
};

int target[20];
int piece[10][4][20];
int bnum[10];

int h[10][4], w[10][4];

vector<P> v[10];
vector<pii> pid;
// int cnt;

// const int dy[] = {-1,0,1,0};
// const int dx[] = {0,1,0,-1};
// bool visited[20][20];
int H, W;

int tmp[20];

bool solve(int now, int t[20]) {
  if (now == pid.size())
    return 1;
  int p = pid[now].second;

  // REP(i,H) {
  //   cout << bitset<20>(t[i]) << endl;
  // }cout << endl;

  REP(i, 20) tmp[i] = t[i];
  for (int i = now; i < pid.size(); ++i) {
    int q = pid[i].second;
    FOR(it, v[q]) {
      bool okf = 1;
      REP(y, h[q][it->d]) {
        int S = t[it->y1 + y] & (piece[q][it->d][y] << it->x1);
        if (S) {
          okf = 0;
          break;
        }
      }
      if (okf) {
        REP(y, h[q][it->d]) tmp[it->y1 + y] |= piece[q][it->d][y] << it->x1;
      }
    }
  }
  REP(i, H) {
    if (tmp[i] != (1 << 20) - 1)
      return 0;
  }
  FOR(it, v[p]) {
    bool okf = 1;
    REP(y, h[p][it->d]) {
      int S = t[it->y1 + y] & (piece[p][it->d][y] << it->x1);
      if (S) {
        okf = 0;
        break;
      }
    }
    if (okf) {
      REP(y, h[p][it->d]) t[it->y1 + y] |= piece[p][it->d][y] << it->x1;
      if (solve(now + 1, t))
        return 1;
      REP(y, h[p][it->d]) t[it->y1 + y] ^= piece[p][it->d][y] << it->x1;
    }
  }
  return 0;
}

int main() {
  while (cin >> H >> W, H || W) {
    REP(i, 20) REP(j, 20) target[i] |= 1 << j;
    int esum = 0;
    REP(y, H) {
      REP(x, W) {
        char c;
        cin >> c;
        if (c == '.') {
          target[y] ^= 1 << x;
          esum++;
        }
      }
    }
    int n;
    cin >> n;

    REP(i, n) {
      bnum[i] = 0;
      cin >> h[i][0] >> w[i][0];
      int tmp[20] = {};
      REP(y, h[i][0]) REP(x, w[i][0]) {
        char c;
        cin >> c;
        if (c == '#') {
          tmp[y] |= 1 << x;
          bnum[i]++;
        }
      }
      REP(d, 4) {
        // REP(j,20) {
        //   cout << bitset<20>(tmp[j]) << endl;
        // } cout << endl;
        REP(j, 20) piece[i][d][j] = tmp[j];
        // rotate
        REP(j, 20) tmp[j] = 0;
        REP(y, h[i][d]) {
          REP(x, w[i][d]) {
            if (piece[i][d][y] >> x & 1)
              tmp[w[i][d] - 1 - x] |= 1 << y;
          }
        }
        if (d < 3) {
          h[i][d + 1] = w[i][d];
          w[i][d + 1] = h[i][d];
        }
      }
    }

    REP(i, n) {
      v[i].clear();
      REP(d, 4) {
        REP(y1, H - h[i][d] + 1) {
          REP(x1, W - w[i][d] + 1) {
            bool okf = 1;
            REP(y, h[i][d]) {
              int S = target[y1 + y] & (piece[i][d][y] << x1);
              if (S) {
                okf = 0;
                break;
              }
            }
            if (okf) {
              v[i].push_back(P(d, y1, x1));
            }
          }
        }
      }
    }
    // REP(i,n) {
    //   cout << i << endl;
    //   FOR(it, v[i]) {
    //     cout << it->d << " " << it->y1 << " " << it->x1 << endl;
    //   }
    // }

    int p;
    cin >> p;
    REP(i, p) {
      int tar[20] = {};
      REP(j, 20) tar[j] = target[j];
      int k;
      cin >> k;
      pid.clear();
      int bsum = 0;
      REP(j, k) {
        int a;
        cin >> a;
        a--;
        pid.push_back(pii(v[a].size(), a));
        bsum += bnum[a];
      }
      sort(ALL(pid));
      if (bsum != esum) {
        cout << "NO" << endl;
      } else {
        if (solve(0, tar)) {
          cout << "YES" << endl;
        } else {
          cout << "NO" << endl;
        }
        // cout << cnt << endl;
      }
    }
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
using namespace std;

#define REP(i, n) for (int i = 0; i < (int)n; ++i)
#define FOR(i, c)                                                              \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define ALL(c) (c).begin(), (c).end()
const int INF = 1 << 29;
typedef pair<int, int> pii;

struct P {
  int d;
  int y1, x1;
  P(int d, int y1, int x1) : d(d), y1(y1), x1(x1) {}
};

int target[20];
int piece[10][4][20];
int bnum[10];

int h[10], w[10];
bool ok[10][4][20][20];
vector<P> v[10];
vector<pii> pid;
int cnt;

bool dp[401];

const int dy[] = {-1, 0, 1, 0};
const int dx[] = {0, 1, 0, -1};
bool visited[20][20];
int H, W;

bool solve(int now, int t[20]) {
  if (now == pid.size())
    return 1;
  // if (cnt++ > 100000) return 0;
  int p = pid[now].second;

  // REP(y,H) {
  //   cout << bitset<20>(t[y]) << endl;
  // } cout << endl;
  dp[0] = 1;
  for (int i = now; i < pid.size(); ++i) {
    for (int j = H * W - bnum[pid[i].second]; j >= 0; --j) {
      dp[j + bnum[pid[i].second]] |= dp[j];
    }
  }

  memset(visited, 0, sizeof(visited));
  REP(y, H) {
    REP(x, W) {
      if (visited[y][x] || (t[y] >> x & 1))
        continue;
      int size = 0;
      queue<pii> Q;
      Q.push(pii(y, x));
      visited[y][x] = 1;
      while (!Q.empty()) {
        pii pi = Q.front();
        Q.pop();
        size++;
        REP(k, 4) {
          int yy = pi.first + dy[k];
          int xx = pi.second + dx[k];
          if (yy < 0 || yy >= H || xx < 0 || xx >= W)
            continue;
          if (visited[yy][xx] || (t[yy] >> xx & 1))
            continue;
          visited[yy][xx] = 1;
          Q.push(pii(yy, xx));
        }
      }
      // cout << now << " " << size << endl;
      if (!dp[size])
        return 0;
    }
  }
  // REP(i,14) {
  //   cout << bitset<20>(t[i]) << endl;
  // } cout << endl;
  FOR(it, v[p]) {
    bool okf = 1;
    REP(y, h[p]) {
      int S = t[it->y1 + y] & (piece[p][it->d][y] << it->x1);
      if (S) {
        okf = 0;
        break;
      }
    }
    if (okf) {
      REP(y, h[p]) t[it->y1 + y] |= piece[p][it->d][y] << it->x1;
      bool f = solve(now + 1, t);
      REP(y, h[p]) t[it->y1 + y] ^= piece[p][it->d][y] << it->x1;
      if (f)
        return 1;
    }
  }
  return 0;
}

int main() {
  while (cin >> H >> W, H || W) {
    REP(i, 20) REP(j, 20) target[i] |= 1 << j;
    int esum = 0;
    REP(y, H) {
      REP(x, W) {
        char c;
        cin >> c;
        if (c == '.') {
          target[y] ^= 1 << x;
          esum++;
        }
      }
    }
    int n;
    cin >> n;

    REP(i, n) {
      bnum[i] = 0;
      cin >> h[i] >> w[i];
      int tmp2[20] = {};
      int y1 = h[i], y2 = 0, x1 = w[i], x2 = 0;
      REP(y, h[i]) REP(x, w[i]) {
        char c;
        cin >> c;
        if (c == '#') {
          y1 = min(y1, y);
          y2 = max(y2, y);
          x1 = min(x1, x);
          x2 = max(x2, x);
          tmp2[y] |= 1 << x;
          bnum[i]++;
        }
      }
      h[i] = y2 - y1 + 1;
      w[i] = x2 - x1 + 1;
      int tmp[20] = {};
      REP(y, h[i])
      tmp[y] = tmp2[y + y1] >> x1;
      REP(d, 4) {
        // REP(j,20) {
        //   cout << bitset<20>(tmp[j]) << endl;
        // } cout << endl;
        assert(tmp[0] != 0);
        REP(j, 20) piece[i][d][j] = tmp[j];
        // rotate
        REP(j, 20) tmp[j] = 0;
        REP(y, h[i]) {
          REP(x, w[i]) {
            if (piece[i][d][y] >> x & 1)
              tmp[w[i] - 1 - x] |= 1 << y;
          }
        }
        swap(h[i], w[i]);
      }
    }

    memset(ok, 0, sizeof(ok));
    REP(i, n) {
      v[i].clear();
      REP(d, 4) {
        REP(y1, H - h[i] + 1) {
          REP(x1, W - w[i] + 1) {
            bool okf = 1;
            REP(y, h[i]) {
              int S = target[y1 + y] & (piece[i][d][y] << x1);
              if (S) {
                okf = 0;
                break;
              }
            }
            if (okf) {
              v[i].push_back(P(d, y1, x1));
            }
          }
        }
      }
    }
    // REP(i,n) {
    //   cout << i << endl;
    //   FOR(it, v[i]) {
    //     cout << it->d << " " << it->y1 << " " << it->x1 << endl;
    //   }
    // }

    int p;
    cin >> p;
    REP(i, p) {
      int k;
      cin >> k;
      pid.clear();
      int bsum = 0;
      REP(j, k) {
        int a;
        cin >> a;
        a--;
        pid.push_back(pii(v[a].size(), a));
        bsum += bnum[a];
      }
      sort(ALL(pid));
      if (bsum != esum) {
        cout << "NO" << endl;
      } else {
        cnt = 0;
        if (solve(0, target)) {
          cout << "YES" << endl;
        } else {
          cout << "NO" << endl;
        }
        // cout << cnt << endl;
      }
    }
  }
}