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

#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;

class P {
public:
  int h, w;
  int bit[22];
  char t[22][22];

  P() {}
  P(int _h, int _w, char _t[22][22]) {
    h = _h;
    w = _w;
    memcpy(t, _t, sizeof(char) * 22 * 22);
    toBit();
  }

  void toBit() {
    for (int i = 0; i < h; i++) {
      bit[i] = 0;
      for (int j = 0; j < w; j++) {
        if (t[i][j] == '#') {
          bit[i] |= (1 << j);
        }
      }
    }
  }

  P rotate() {
    char tmp[22][22];

    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        tmp[j][h - i - 1] = t[i][j];
      }
    }
    return P(w, h, tmp);
  }

  void toCompact() {
    int subH = 0;

    for (int i = 0; i < h; i++) {
      bool flg = true;
      for (int j = 0; j < w; j++) {
        if (t[i][j] != '#')
          continue;
        flg = false;
        break;
      }

      if (flg)
        subH++;
      else
        break;
    }

    h -= subH;

    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        t[i][j] = t[i + subH][j];
      }
    }

    int subW = 0;

    for (int j = 0; j < w; j++) {
      bool flg = true;
      for (int i = 0; i < h; i++) {
        if (t[i][j] != '#')
          continue;
        flg = false;
        break;
      }

      if (flg)
        subW++;
      else
        break;
    }

    w -= subW;

    for (int j = 0; j < w; j++) {
      for (int i = 0; i < h; i++) {
        t[i][j] = t[i][j + subW];
      }
    }

    subH = 0;
    for (int i = h - 1; i >= 0; i--) {
      bool flg = true;
      for (int j = 0; j < w; j++) {
        if (t[i][j] != '#')
          continue;
        flg = false;
        break;
      }

      if (flg)
        subH++;
      else
        break;
    }
    h -= subH;

    subW = 0;
    for (int j = w - 1; j >= 0; j--) {
      bool flg = true;
      for (int i = 0; i < h; i++) {
        if (t[i][j] != '#')
          continue;
        flg = false;
        break;
      }

      if (flg)
        subW++;
      else
        break;
    }
    w -= subW;

    toBit();
  }

  void show() {
    cout << "--\\n";
    cout << h << " " << w << endl;
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        cout << t[i][j];
      }
      cout << endl;
    }
  }
};

int H, W, n;
int tcnt, pcnt[12];
int bit[22], bit_tmp[22];
char t[22][22];
P p[12][4];
vector<int> sx[12][4], sy[12][4];

int m;
int v[12];

bool cmp(const int &x, const int &y) { return pcnt[x] > pcnt[y]; }

bool match(const P &pc, int si, int sj) {
  for (int i = 0; i < pc.h; i++) {
    if (((pc.bit[i] << sj) & bit[si + i]) != 0) {
      return false;
    }
  }
  return true;
}

void calcPos() {
  for (int kind = 0; kind < n; kind++) {
    for (int d = 0; d < 4; d++) {
      sx[kind][d].clear();
      sy[kind][d].clear();

      for (int si = 0; si + p[kind][d].h <= H; si++) {
        for (int sj = 0; sj + p[kind][d].w <= W; sj++) {
          if (!match(p[kind][d], si, sj))
            continue;
          sx[kind][d].push_back(sj);
          sy[kind][d].push_back(si);
        }
      }
    }
  }
}

void draw(const P &pc, int si, int sj, int table[22], bool orFlg = false) {
  for (int i = 0; i < pc.h; i++) {
    if (orFlg) {
      table[si + i] |= (pc.bit[i] << sj);
    } else {
      table[si + i] ^= (pc.bit[i] << sj);
    }
  }
}

bool check(int idx) {
  for (int i = 0; i < H; i++) {
    bit_tmp[i] = bit[i];
  }

  for (int i = idx; i < m; i++) {
    int kind = v[i];
    bool flg = false;

    for (int d = 0; d < 4; d++) {
      for (int j = 0; j < sx[kind][d].size(); j++) {
        if (match(p[kind][d], sy[kind][d][j], sx[kind][d][j])) {
          draw(p[kind][d], sy[kind][d][j], sx[kind][d][j], bit_tmp, true);
          flg = true;
        }
      }
    }
    if (!flg)
      return false;
  }

  for (int i = 0; i < H; i++) {
    if (bit_tmp[i] != (1 << W) - 1) {
      return false;
    }
  }

  return true;
}

bool dfs(int idx) {
  if (idx == m) {
    return true;
  }

  if (0 < idx && !check(idx)) {
    return false;
  }

  int kind = v[idx];

  for (int d = 0; d < 4; d++) {
    for (int i = 0; i < sx[kind][d].size(); i++) {
      if (!match(p[kind][d], sy[kind][d][i], sx[kind][d][i]))
        continue;
      draw(p[kind][d], sy[kind][d][i], sx[kind][d][i], bit);
      bool tmp = dfs(idx + 1);
      draw(p[kind][d], sy[kind][d][i], sx[kind][d][i], bit);

      if (tmp)
        return true;
    }
  }

  return false;
}

bool solve() {
  int sumCnt = 0;
  for (int i = 0; i < m; i++) {
    sumCnt += pcnt[v[i]];
  }
  if (sumCnt != tcnt)
    return false;

  sort(v, v + m, cmp);

  return dfs(0);
}

int main() {
  while (cin >> H >> W, H || W) {
    tcnt = 0;
    for (int i = 0; i < H; i++) {
      cin >> t[i];
      bit[i] = 0;

      for (int j = 0; j < W; j++) {
        if (t[i][j] == '.') {
          tcnt++;
        } else {
          bit[i] |= (1 << j);
        }
      }
    }

    cin >> n;

    for (int i = 0; i < n; i++) {
      int h, w;
      char tmp[22][22];
      cin >> h >> w;
      pcnt[i] = 0;

      for (int j = 0; j < h; j++) {
        cin >> tmp[j];

        for (int k = 0; k < w; k++) {
          if (tmp[j][k] == '#') {
            pcnt[i]++;
          }
        }
      }

      p[i][0] = P(h, w, tmp);
      p[i][0].toCompact();
      for (int j = 1; j < 4; j++) {
        p[i][j] = p[i][j - 1].rotate();
      }
    }

    calcPos();

    int Q;
    cin >> Q;

    for (int i = 0; i < Q; i++) {
      cin >> m;
      for (int j = 0; j < m; j++) {
        cin >> v[j];
        v[j]--;
      }

      cout << (solve() ? "YES" : "NO") << endl;
    }
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;

class P {
public:
  int h, w;
  int bit[22];
  char t[22][22];

  P() {}
  P(int _h, int _w, char _t[22][22]) {
    h = _h;
    w = _w;
    memcpy(t, _t, sizeof(char) * 22 * 22);
    toBit();
  }

  void toBit() {
    for (int i = 0; i < h; i++) {
      bit[i] = 0;
      for (int j = 0; j < w; j++) {
        if (t[i][j] == '#') {
          bit[i] |= (1 << j);
        }
      }
    }
  }

  P rotate() {
    char tmp[22][22];

    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        tmp[j][h - i - 1] = t[i][j];
      }
    }
    return P(w, h, tmp);
  }

  void toCompact() {
    int subH = 0;

    for (int i = 0; i < h; i++) {
      bool flg = true;
      for (int j = 0; j < w; j++) {
        if (t[i][j] != '#')
          continue;
        flg = false;
        break;
      }

      if (flg)
        subH++;
      else
        break;
    }

    h -= subH;

    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        t[i][j] = t[i + subH][j];
      }
    }

    int subW = 0;

    for (int j = 0; j < w; j++) {
      bool flg = true;
      for (int i = 0; i < h; i++) {
        if (t[i][j] != '#')
          continue;
        flg = false;
        break;
      }

      if (flg)
        subW++;
      else
        break;
    }

    w -= subW;

    for (int j = 0; j < w; j++) {
      for (int i = 0; i < h; i++) {
        t[i][j] = t[i][j + subW];
      }
    }

    subH = 0;
    for (int i = h - 1; i >= 0; i--) {
      bool flg = true;
      for (int j = 0; j < w; j++) {
        if (t[i][j] != '#')
          continue;
        flg = false;
        break;
      }

      if (flg)
        subH++;
      else
        break;
    }
    h -= subH;

    subW = 0;
    for (int j = w - 1; j >= 0; j--) {
      bool flg = true;
      for (int i = 0; i < h; i++) {
        if (t[i][j] != '#')
          continue;
        flg = false;
        break;
      }

      if (flg)
        subW++;
      else
        break;
    }
    w -= subW;

    toBit();
  }

  void show() {
    cout << "--\\n";
    cout << h << " " << w << endl;
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        cout << t[i][j];
      }
      cout << endl;
    }
  }
};

int H, W, n;
int tcnt, pcnt[12];
int bit[22];
char t[22][22];
P p[12][4];
vector<int> sx[12][4], sy[12][4];

int m;
int v[12];

bool cmp(const int &x, const int &y) { return pcnt[x] > pcnt[y]; }

bool match(const P &pc, int si, int sj) {
  for (int i = 0; i < pc.h; i++) {
    if (((pc.bit[i] << sj) & bit[si + i]) != 0) {
      return false;
    }
  }
  return true;
}

void calcPos() {
  for (int kind = 0; kind < n; kind++) {
    for (int d = 0; d < 4; d++) {
      sx[kind][d].clear();
      sy[kind][d].clear();

      for (int si = 0; si + p[kind][d].h <= H; si++) {
        for (int sj = 0; sj + p[kind][d].w <= W; sj++) {
          if (!match(p[kind][d], si, sj))
            continue;
          sx[kind][d].push_back(sj);
          sy[kind][d].push_back(si);
        }
      }
    }
  }
}

void draw(const P &pc, int si, int sj) {
  for (int i = 0; i < pc.h; i++) {
    bit[si + i] ^= (pc.bit[i] << sj);
  }
}

bool check(int idx) {
  for (int i = idx; i < m; i++) {
    int kind = v[i];
    bool flg = false;

    for (int d = 0; !flg && d < 4; d++) {
      for (int j = 0; j < sx[kind][d].size(); j++) {
        if (match(p[kind][d], sy[kind][d][j], sx[kind][d][j])) {
          flg = true;
          break;
        }
      }
    }
    if (!flg)
      return false;
  }
  return true;
}

bool dfs(int idx) {
  if (idx == m) {
    return true;
  }

  if (0 < idx && !check(idx)) {
    return false;
  }

  int kind = v[idx];

  for (int d = 0; d < 4; d++) {
    for (int i = 0; i < sx[kind][d].size(); i++) {
      if (!match(p[kind][d], sy[kind][d][i], sx[kind][d][i]))
        continue;
      draw(p[kind][d], sy[kind][d][i], sx[kind][d][i]);
      bool tmp = dfs(idx + 1);
      draw(p[kind][d], sy[kind][d][i], sx[kind][d][i]);

      if (tmp)
        return true;
    }
  }

  return false;
}

bool solve() {
  int sumCnt = 0;
  for (int i = 0; i < m; i++) {
    sumCnt += pcnt[v[i]];
  }
  if (sumCnt != tcnt)
    return false;

  sort(v, v + m, cmp);

  return dfs(0);
}

int main() {
  while (cin >> H >> W, H || W) {
    tcnt = 0;
    for (int i = 0; i < H; i++) {
      cin >> t[i];
      bit[i] = 0;

      for (int j = 0; j < W; j++) {
        if (t[i][j] == '.') {
          tcnt++;
        } else {
          bit[i] |= (1 << j);
        }
      }
    }

    cin >> n;

    for (int i = 0; i < n; i++) {
      int h, w;
      char tmp[22][22];
      cin >> h >> w;
      pcnt[i] = 0;

      for (int j = 0; j < h; j++) {
        cin >> tmp[j];

        for (int k = 0; k < w; k++) {
          if (tmp[j][k] == '#') {
            pcnt[i]++;
          }
        }
      }

      p[i][0] = P(h, w, tmp);
      p[i][0].toCompact();
      for (int j = 1; j < 4; j++) {
        p[i][j] = p[i][j - 1].rotate();
      }
    }

    calcPos();

    int Q;
    cin >> Q;

    for (int i = 0; i < Q; i++) {
      cin >> m;
      for (int j = 0; j < m; j++) {
        cin >> v[j];
        v[j]--;
      }

      cout << (solve() ? "YES" : "NO") << endl;
    }
  }
}