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

#include <algorithm>
#include <deque>
#include <iostream>
#include <set>
#include <vector>
using namespace std;
#define rep(i, n) for (int i = 0; i < n; i++)
#define all(n) n.begin(), n.end()
typedef long long ll;

int bx[20];
int xbit[10][4][20];
int H[10][4], W[10][4];
int pzlCnt[10];
int num[10];

int generate(int _bx[20], deque<string> t, char del, int &_H, int &_W) {
  rep(i, 20) _bx[i] = 0;
  while (count(all(t[0]), del) == t[0].size())
    t.pop_front();
  while (count(all(t[t.size() - 1]), del) == t[t.size() - 1].size())
    t.pop_back();
  while (1) {
    bool f = true;
    rep(i, t.size()) f &= t[i][0] == del;
    if (f)
      rep(i, t.size()) t[i] = t[i].substr(1);
    else
      break;
  }
  while (1) {
    bool f = true;
    rep(i, t.size()) f &= t[i][t[i].size() - 1] == del;
    if (f)
      rep(i, t.size()) t[i] = t[i].erase(t[i].size() - 1);
    else
      break;
  }
  int H = t.size(), W = t[0].length();
  // rep(i,t.size()) cout << t[i] << endl;

  rep(i, H) rep(j, W) _bx[i] |= ((t[i][j] == '#') << j);
  _W = W, _H = H;
}

string genEmpty(char c, int l) {
  string ans;
  rep(i, l) ans += c;
  return ans;
}
void fix(deque<string> &t) {
  int mxsz = max(t.size(), t[0].size());
  rep(i, t.size()) while (t[i].size() < mxsz) t[i] += '.';
  while (t.size() < mxsz)
    t.push_back(genEmpty('.', mxsz));
}
void rotate(deque<string> &t) {
  rep(i, t.size()) rep(j, i) swap(t[i][j], t[j][i]);
  rep(i, t.size()) reverse(all(t[i]));
}

int h, w, P;
int v[10];
int cx[20];

bool isok(int ax[20], int tx[20], int x, int y) {
  rep(i, 20) if (ax[i + y] & (tx[i] << x)) return false;
  return true;
}
void add(int a[20], int b[20], int x, int y) {
  rep(i, 20) a[i + y] |= (b[i] << x);
}
void sub(int a[20], int b[20], int x, int y) {
  rep(i, 20) a[i + y] &= ~(b[i] << x);
}

void output(int a[20]) {
  rep(i, h) {
    rep(j, w) cout << !!((1 << j) & a[i]);
    cout << endl;
  }
}

struct NODE {
  int v[20];
  NODE(int a[20]) { rep(i, 20) v[i] = a[i]; }
};
bool operator<(const NODE &a, const NODE &b) {
  rep(i, 20) {
    if (a.v[i] != b.v[i])
      return a.v[i] < b.v[i];
  }
  return false;
}

set<NODE> memo[10];

int dfs(int k) {
  if (k == P)
    return true;

  NODE key(cx);
  if (memo[k].find(key) != memo[k].end())
    return false;
  else
    memo[k].insert(key);

  int cur = v[k];

  int pre[20] = {0};
  for (int f = k; f < P; f++) {
    int c = v[f];
    rep(d, 4) {
      rep(i, h - H[c][d] + 1) {
        rep(j, w - W[c][d] + 1) {
          if (isok(cx, xbit[c][d], j, i)) {
            add(pre, xbit[c][d], j, i);
          }
        }
      }
    }
  }
  rep(i, h) {
    if (pre[i] != ((~cx[i]) & ((1 << w) - 1)))
      return false;
  }
  rep(d, 4) {
    rep(i, h - H[cur][d] + 1) {
      rep(j, w - W[cur][d] + 1) {
        if (isok(cx, xbit[cur][d], j, i)) {
          add(cx, xbit[cur][d], j, i);
          if (dfs(k + 1))
            return true;
          sub(cx, xbit[cur][d], j, i);
        }
      }
    }
  }

  return false;
}

int _2dCount(deque<string> &t, char c) {
  int ans = 0;
  rep(i, t.size()) rep(j, t[i].size()) ans += t[i][j] == c;
  return ans;
}

void _swap(int a, int b) {
  rep(i, 4) rep(j, 20) swap(xbit[a][i][j], xbit[b][i][j]);
  swap(pzlCnt[a], pzlCnt[b]);
  swap(num[a], num[b]);
  rep(i, 4) swap(H[a][i], H[b][i]);
  rep(i, 4) swap(W[a][i], W[b][i]);
}

int issame(int a[20], int b[20]) {
  rep(i, 20) if (a[i] != b[i]) return false;
  return true;
}
int main() {
  string t;
  deque<string> tmp;
  while (cin >> h >> w && h || w) {
    rep(i, 10) num[i] = i;

    tmp.clear();
    rep(i, h) cin >> t, tmp.push_back(t);

    generate(bx, tmp, '-', h, w);
    int allCnt = _2dCount(tmp, '.');
    int N;
    cin >> N;
    rep(k, N) {
      tmp.clear();
      int th, tw;
      cin >> th >> tw;
      rep(i, th) cin >> t, tmp.push_back(t);
      pzlCnt[k] = _2dCount(tmp, '#');
      // cout << pzlCnt[k] << endl;
      fix(tmp);
      rep(d, 4) {
        generate(xbit[k][d], tmp, '.', H[k][d], W[k][d]);
        // rep(i,tmp.size()) cout << tmp[i] << endl;
        // rep(i,H[k][d]) cout << xbit[k][d][i] << " " ;cout << endl;
        // cout << W[k][d] << " " << H[k][d] << endl;
        // cout << endl;
        rotate(tmp);
      }
    }
    /*rep(i,N)rep(j,N-1){
            if(pzlCnt[j] < pzlCnt[j+1]){
                    _swap(j,j+1);
            }
    }*/
    int Q;
    cin >> Q;
    rep(x, Q) {
      rep(i, 10) memo[i].clear();
      rep(i, 20) cx[i] = bx[i];
      int qCnt = 0;
      cin >> P;
      rep(j, P) cin >> v[j], v[j] = find(num, num + 10, v[j] - 1) - num,
                             qCnt += pzlCnt[v[j]];
      if (qCnt == allCnt && dfs(0)) {
        cout << "YES" << endl;
      } else {
        cout << "NO" << endl;
      }
      /*	for(set<NODE>::iterator it = memo[0].begin();it !=
      memo[0].end();++it){ output((int *)(*it).v); cout << endl;
      }*/
    }
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <deque>
#include <iostream>
#include <set>
#include <vector>
using namespace std;
#define rep(i, n) for (int i = 0; i < n; i++)
#define all(n) n.begin(), n.end()
typedef long long ll;

int bx[20];
int xbit[10][4][20];
int H[10][4], W[10][4];
int pzlCnt[10];
int num[10];

int generate(int _bx[20], deque<string> t, char del, int &_H, int &_W) {
  rep(i, 20) _bx[i] = 0;
  while (count(all(t[0]), del) == t[0].size())
    t.pop_front();
  while (count(all(t[t.size() - 1]), del) == t[t.size() - 1].size())
    t.pop_back();
  while (1) {
    bool f = true;
    rep(i, t.size()) f &= t[i][0] == del;
    if (f)
      rep(i, t.size()) t[i] = t[i].substr(1);
    else
      break;
  }
  while (1) {
    bool f = true;
    rep(i, t.size()) f &= t[i][t[i].size() - 1] == del;
    if (f)
      rep(i, t.size()) t[i] = t[i].erase(t[i].size() - 1);
    else
      break;
  }
  int H = t.size(), W = t[0].length();
  // rep(i,t.size()) cout << t[i] << endl;

  rep(i, H) rep(j, W) _bx[i] |= ((t[i][j] == '#') << j);
  _W = W, _H = H;
}

string genEmpty(char c, int l) {
  string ans;
  rep(i, l) ans += c;
  return ans;
}
void fix(deque<string> &t) {
  int mxsz = max(t.size(), t[0].size());
  rep(i, t.size()) while (t[i].size() < mxsz) t[i] += '.';
  while (t.size() < mxsz)
    t.push_back(genEmpty('.', mxsz));
}
void rotate(deque<string> &t) {
  rep(i, t.size()) rep(j, i) swap(t[i][j], t[j][i]);
  rep(i, t.size()) reverse(all(t[i]));
}

int h, w, P;
int v[10];
int cx[20];

bool isok(int ax[20], int tx[20], int x, int y) {
  rep(i, 20) if (ax[i + y] & (tx[i] << x)) return false;
  return true;
}
void add(int a[20], int b[20], int x, int y) {
  rep(i, 20) a[i + y] |= (b[i] << x);
}
void sub(int a[20], int b[20], int x, int y) {
  rep(i, 20) a[i + y] &= ~(b[i] << x);
}

void output(int a[20]) {
  rep(i, h) {
    rep(j, w) cout << !!((1 << j) & a[i]);
    cout << endl;
  }
}

struct NODE {
  int v[20];
  NODE(int a[20]) { rep(i, 20) v[i] = a[i]; }
};
bool operator<(const NODE &a, const NODE &b) {
  rep(i, 20) {
    if (a.v[i] != b.v[i])
      return a.v[i] < b.v[i];
  }
  return false;
}

set<NODE> memo[10];

int dfs(int k) {
  // rep(i,10)cout << memo[i].size() << " ";cout << endl;
  // cout << k << endl;
  // output(cx);
  // usleep(300000);
  if (k == P)
    return true;
  // output((int *)key.v);
  NODE key(cx);
  if (memo[k].find(key) != memo[k].end())
    return false;
  else
    memo[k].insert(key);

  int cur = v[k];
  // cout << cur << endl;
  rep(d, 4) {
    // cout << ")" << cur << "|" << d << " " << W[d][cur] << "-" <<  H[d][cur]
    // << endl; cout << " " << cur << "|" << d << " " << w-W[d][cur]+1 << "-" <<
    // h-H[d][cur]+1 << endl;
    rep(i, h - H[cur][d] + 1) {
      rep(j, w - W[cur][d] + 1) {
        if (isok(cx, xbit[cur][d], j, i)) {
          add(cx, xbit[cur][d], j, i);
          // cout << "isok" << j << " " << i << endl;
          if (dfs(k + 1))
            return true;
          sub(cx, xbit[cur][d], j, i);
        }
      }
    }
  }
  // cout << "Error" << endl;
  return false;
}

int _2dCount(deque<string> &t, char c) {
  int ans = 0;
  rep(i, t.size()) rep(j, t[i].size()) ans += t[i][j] == c;
  return ans;
}

void _swap(int a, int b) {
  rep(i, 4) rep(j, 20) swap(xbit[a][i][j], xbit[b][i][j]);
  swap(pzlCnt[a], pzlCnt[b]);
  swap(num[a], num[b]);
  rep(i, 4) swap(H[a][i], H[b][i]);
  rep(i, 4) swap(W[a][i], W[b][i]);
}
int main() {
  string t;
  deque<string> tmp;
  while (cin >> h >> w && h || w) {
    rep(i, 10) num[i] = i;

    tmp.clear();
    rep(i, h) cin >> t, tmp.push_back(t);

    generate(bx, tmp, '-', h, w);
    int allCnt = _2dCount(tmp, '.');
    int N;
    cin >> N;
    rep(k, N) {
      tmp.clear();
      int th, tw;
      cin >> th >> tw;
      rep(i, th) cin >> t, tmp.push_back(t);
      pzlCnt[k] = _2dCount(tmp, '#');
      // cout << pzlCnt[k] << endl;
      fix(tmp);
      rep(d, 4) {
        generate(xbit[k][d], tmp, '.', H[k][d], W[k][d]);
        // rep(i,tmp.size()) cout << tmp[i] << endl;
        // rep(i,H[k][d]) cout << xbit[k][d][i] << " " ;cout << endl;
        // cout << W[k][d] << " " << H[k][d] << endl;
        // cout << endl;
        rotate(tmp);
      }
    }
    rep(i, N) rep(j, N - 1) {
      if (pzlCnt[j] < pzlCnt[j + 1]) {
        _swap(j, j + 1);
      }
    }
    int Q;
    cin >> Q;
    rep(x, Q) {
      rep(i, 10) memo[i].clear();
      rep(i, 20) cx[i] = bx[i];
      int qCnt = 0;
      cin >> P;
      rep(j, P) cin >> v[j], v[j] = find(num, num + 10, v[j] - 1) - num,
                             qCnt += pzlCnt[v[j]];
      if (qCnt == allCnt && dfs(0)) {
        cout << "YES" << endl;
      } else {
        cout << "NO" << endl;
      }
      /*	for(set<NODE>::iterator it = memo[0].begin();it !=
      memo[0].end();++it){ output((int *)(*it).v); cout << endl;
      }*/
    }
  }
}