Problem p00132 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <vector>
#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define inf (1 << 28)
#define MAX 31
using namespace std;
typedef pair<int, int> ii;
typedef vector<string> vs;
typedef vector<vs> vvs;
int h, w, n, p, k;
int t[30];
char G[MAX][MAX];
char piece[MAX][4][60][60];
ii hw[4][MAX]; // ii(h,w)
int GOMAKASHI[MAX];
ii order[MAX];
int total;
bool complete;
bool debug;

void print(int one, int dir) {

  if (one < 0) {
    rep(i, h) {
      rep(j, w) { cout << G[i][j]; }
      cout << endl;
    }
    cout << endl;
    return;
  }

  int H = hw[dir][one].first;
  int W = hw[dir][one].second;
  rep(i, H) {
    rep(j, W) { cout << piece[one][dir][i][j]; }
    cout << endl;
  }
  cout << endl;
}

void rotate90(int one, int dir) { // verify [ok]

  int H = hw[dir][one].first;
  int W = hw[dir][one].second;
  hw[(dir + 1) % 4][one] = ii(W, H);
  int pos = 0;

  char tmp[W][H];

  rep(i, W) {
    rep(j, H) { tmp[i][j] = piece[one][dir][(H - 1) - j][i]; }
  }

  swap(H, W);

  rep(i, H) {
    rep(j, W) { piece[one][(dir + 1) % 4][i][j] = tmp[i][j]; }
  }
}

bool check(int x, int y, int one, int dir) { // verify [ok]
  int H = hw[dir][one].first;
  int W = hw[dir][one].second;
  // cout << "H = " << H << " W = " << W << endl;
  rep(i, H) {
    rep(j, W) {
      if (piece[one][dir][i][j] == '.')
        continue;
      int nx = j + x;
      int ny = i + y;
      if (!(0 <= nx && nx < w && 0 <= ny && ny < h)) {
        if (piece[one][dir][i][j] == '#') {

          return false;
        }
        continue;
      }

      if (G[ny][nx] == piece[one][dir][i][j]) {

        return false;
      }
    }
  }
  return true;
}

void draw(int x, int y, int one, bool flag,
          int dir) // flag == true? draw : erase
{                  // verify [ok]
  int H = hw[dir][one].first;
  int W = hw[dir][one].second;
  rep(i, H) {
    rep(j, W) {
      int nx = j + x;
      int ny = i + y;
      if (!(0 <= nx && nx < w && 0 <= ny && ny < h)) {
        assert(piece[one][dir][i][j] == '.');
        continue;
      }
      if (piece[one][dir][i][j] == '.')
        continue;
      if (flag)
        assert(G[ny][nx] == '.');
      if (!flag)
        assert(G[ny][nx] == '#');
      G[ny][nx] = (flag ? '#' : '.');
    }
  }
}

bool finish() { // veritfy [ok]
  rep(i, h) rep(j, w) if (G[i][j] == '.') return false;
  return true;
}

void dfs(int x, int y, int used) { // verify [no]
  if (y >= h) {
    // print(-1);
    complete = true;
    rep(i, 10) {
      if (!((used >> i) & 1))
        complete = false;
      break;
    }
    return;
  }

  if (complete)
    return;

  REP(i, y, h) // y
  // rep(i,h)//y
  {

    REP(j, 0, w) // x
    // rep(j,w)//x
    {
      // cout << j << "," << i << endl;

      // rep(l,n)//which one
      int v = 0;
      for (int l = order[v].first; l != -inf; l = order[++v].first) {
        if ((used >> l) & 1)
          continue;

        rep(_, 4) // rotate
        {
          if (!check(j, i, l, _)) {
            continue;
          }

          if (!complete) {
            /*
if(__builtin_popcount(used) == 5 && !((used >> 1) & 1) && ((used >> 6) & 1) && i
== 1 && j > 7)
            */
            draw(j, i, l, true, _);

            dfs(j, i, used | (1 << l));

            draw(j, i, l, false, _);
            if (complete)
              return;
          }
        }
      }
      if (complete)
        return;
      if (G[i][j] == '.')
        return;
      // if(!next || complete)return;
    }
  }

  if (complete)
    return;

  // if(finish())
  //{
  // print(-1);
  complete = true;
  rep(i, 10) {
    if (!((used >> i) & 1)) {
      complete = false;
      break;
    }
  }
  //}
}

void Input() { // verify [ok]
  total = 0;
  rep(i, h) {
    rep(j, w) {
      cin >> G[i][j];
      if (G[i][j] == '.')
        total++;
    }
  }
  rep(i, MAX) GOMAKASHI[i] = 0;

  rep(i, MAX) rep(j, 4) rep(l, 60) rep(m, 60) piece[i][j][l][m] = '.';

  cin >> n;
  rep(i, n) {
    int ph, pw;
    cin >> ph >> pw;
    hw[0][i] = ii(ph, pw);
    rep(j, ph) {
      rep(l, pw) { cin >> piece[i][0][j][l]; }
    }
    rep(j, ph) rep(l, pw) if (piece[i][0][j][l] == '#') GOMAKASHI[i]++;
    rotate90(i, 0);
    rotate90(i, 1);
    rotate90(i, 2);
    // print(i,0);
    // print(i,1);
    // print(i,2);
    // print(i,3);
    // cout << "-----------------" << endl;
  }
}

bool cmp(const ii &a, const ii &b) { return a.second > b.second; }

int main() {
  while (cin >> h >> w, h | w) {
    Input();
    cin >> p;
    while (p--) {
      cin >> k;
      rep(i, 11) t[i] = false;
      int init = 0;
      int gomakashi = 0;
      rep(i, k) {
        int th;
        cin >> th;
        th--;
        order[i] = ii(th, hw[0][th].first * hw[0][th].second);
        t[th] = true;
        gomakashi += GOMAKASHI[th];
      }
      rep(i, 11) if (!t[i]) init |= (1 << i);
      order[k] = ii(-inf, -inf);
      sort(order, order + k, cmp);

      complete = false;
      if (gomakashi == total)
        dfs(0, 0, init);
      cout << (complete ? "YES" : "NO") << endl;
    }
  }
  return 0;
}

Fixed submission:
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <vector>
#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define inf (1 << 28)
#define MAX 31
using namespace std;
typedef pair<int, int> ii;
typedef vector<string> vs;
typedef vector<vs> vvs;
int h, w, n, p, k;
int t[30];
char G[MAX][MAX];
char piece[MAX][4][60][60];
ii hw[4][MAX]; // ii(h,w)
int GOMAKASHI[MAX];
ii order[MAX];
int total;
bool complete;
bool debug;

void print(int one, int dir) {

  if (one < 0) {
    rep(i, h) {
      rep(j, w) { cout << G[i][j]; }
      cout << endl;
    }
    cout << endl;
    return;
  }

  int H = hw[dir][one].first;
  int W = hw[dir][one].second;
  rep(i, H) {
    rep(j, W) { cout << piece[one][dir][i][j]; }
    cout << endl;
  }
  cout << endl;
}

void rotate90(int one, int dir) { // verify [ok]

  int H = hw[dir][one].first;
  int W = hw[dir][one].second;
  hw[(dir + 1) % 4][one] = ii(W, H);
  int pos = 0;

  char tmp[W][H];

  rep(i, W) {
    rep(j, H) { tmp[i][j] = piece[one][dir][(H - 1) - j][i]; }
  }

  swap(H, W);

  rep(i, H) {
    rep(j, W) { piece[one][(dir + 1) % 4][i][j] = tmp[i][j]; }
  }
}

bool check(int x, int y, int one, int dir) { // verify [ok]
  int H = hw[dir][one].first;
  int W = hw[dir][one].second;
  // cout << "H = " << H << " W = " << W << endl;
  rep(i, H) {
    rep(j, W) {
      if (piece[one][dir][i][j] == '.')
        continue;
      int nx = j + x;
      int ny = i + y;
      if (!(0 <= nx && nx < w && 0 <= ny && ny < h)) {
        if (piece[one][dir][i][j] == '#') {

          return false;
        }
        continue;
      }

      if (G[ny][nx] == piece[one][dir][i][j]) {

        return false;
      }
    }
  }
  return true;
}

void draw(int x, int y, int one, bool flag,
          int dir) // flag == true? draw : erase
{                  // verify [ok]
  int H = hw[dir][one].first;
  int W = hw[dir][one].second;
  rep(i, H) {
    rep(j, W) {
      int nx = j + x;
      int ny = i + y;
      if (!(0 <= nx && nx < w && 0 <= ny && ny < h)) {
        assert(piece[one][dir][i][j] == '.');
        continue;
      }
      if (piece[one][dir][i][j] == '.')
        continue;
      if (flag)
        assert(G[ny][nx] == '.');
      if (!flag)
        assert(G[ny][nx] == '#');
      G[ny][nx] = (flag ? '#' : '.');
    }
  }
}

bool finish() { // veritfy [ok]
  rep(i, h) rep(j, w) if (G[i][j] == '.') return false;
  return true;
}

void dfs(int x, int y, int used) { // verify [no]
  if (y >= h) {
    // print(-1);
    complete = true;
    rep(i, 10) {
      if (!((used >> i) & 1))
        complete = false;
      break;
    }
    return;
  }

  if (complete)
    return;

  // bitset<10> use(used);
  // cout << "use : " << use << endl;

  bool cut[h][w];
  rep(i, h) rep(j, w) cut[i][j] = false;

  rep(i, h) {
    rep(j, w) {
      if (G[i][j] == '#')
        cut[i][j] = true;
      int v = 0;
      for (int l = order[v].first; l != -inf; l = order[++v].first) {
        if ((used >> l) & 1)
          continue;
        rep(m, 4) {
          if (!check(j, i, l, m))
            continue;
          rep(o, hw[m][l].first) {
            rep(p, hw[m][l].second) {
              if (piece[l][m][o][p] == '.')
                continue;
              cut[i + o][j + p] = true;
            }
          }
        }
      }
      if (!cut[i][j]) {
        // cout << "NO WAY!!! " << j << "," << i << endl;
        return;
      }
    }
  }

  REP(i, y, h) // y
  // rep(i,h)//y
  {

    REP(j, 0, w) // x
    // rep(j,w)//x
    {
      // cout << j << "," << i << endl;

      // rep(l,n)//which one
      int v = 0;
      for (int l = order[v].first; l != -inf; l = order[++v].first) {
        if ((used >> l) & 1)
          continue;

        rep(_, 4) // rotate
        {
          if (!check(j, i, l, _)) {
            continue;
          }

          if (!complete) {
            /*
if(__builtin_popcount(used) == 5 && !((used >> 1) & 1) && ((used >> 6) & 1) && i
== 1 && j > 7)
            */
            draw(j, i, l, true, _);

            dfs(j, i, used | (1 << l));

            draw(j, i, l, false, _);
            if (complete)
              return;
          }
        }
      }
      if (complete)
        return;
      if (G[i][j] == '.')
        return;
      // if(!next || complete)return;
    }
  }

  if (complete)
    return;

  // if(finish())
  //{
  // print(-1);
  complete = true;
  rep(i, 10) {
    if (!((used >> i) & 1)) {
      complete = false;
      break;
    }
  }
  //}
}

void Input() { // verify [ok]
  total = 0;
  rep(i, h) {
    rep(j, w) {
      cin >> G[i][j];
      if (G[i][j] == '.')
        total++;
    }
  }
  rep(i, MAX) GOMAKASHI[i] = 0;

  rep(i, MAX) rep(j, 4) rep(l, 60) rep(m, 60) piece[i][j][l][m] = '.';

  cin >> n;
  rep(i, n) {
    int ph, pw;
    cin >> ph >> pw;
    hw[0][i] = ii(ph, pw);
    rep(j, ph) {
      rep(l, pw) { cin >> piece[i][0][j][l]; }
    }
    rep(j, ph) rep(l, pw) if (piece[i][0][j][l] == '#') GOMAKASHI[i]++;
    rotate90(i, 0);
    rotate90(i, 1);
    rotate90(i, 2);
    // print(i,0);
    // print(i,1);
    // print(i,2);
    // print(i,3);
    // cout << "-----------------" << endl;
  }
}

bool cmp(const ii &a, const ii &b) { return a.second > b.second; }

int main() {
  while (cin >> h >> w, h | w) {
    Input();
    cin >> p;
    while (p--) {
      cin >> k;
      rep(i, 11) t[i] = false;
      int init = 0;
      int gomakashi = 0;
      rep(i, k) {
        int th;
        cin >> th;
        th--;
        order[i] = ii(th, hw[0][th].first * hw[0][th].second);
        t[th] = true;
        gomakashi += GOMAKASHI[th];
      }
      rep(i, 11) if (!t[i]) init |= (1 << i);
      order[k] = ii(-inf, -inf);
      sort(order, order + k, cmp);

      complete = false;
      if (gomakashi == total)
        dfs(0, 0, init);
      cout << (complete ? "YES" : "NO") << endl;
    }
  }
  return 0;
}