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

#include <bits/stdc++.h>
using namespace std;

#define BIT(x) (1 << (x))

struct Piece {
  int h, w;
  vector<int> v;
};

int H, W;
int n;
int board[20];
Piece p[10][4];

void generate(vector<vector<int>> v, Piece p[]) {
  for (int i = 0; i < 4; i++) {
    int bx = 20, by = 20, ex = -1, ey = -1;
    for (int j = 0; j < 20; j++) {
      for (int k = 0; k < 20; k++) {
        if (v[j][k]) {
          bx = min(bx, j);
          by = min(by, k);
          ex = max(ex, j);
          ey = max(ey, k);
        }
      }
    }
    p[i].h = ex - bx + 1;
    p[i].w = ey - by + 1;
    p[i].v.assign(p[i].h, 0);
    for (int j = 0; j < p[i].h; j++) {
      for (int k = 0; k < p[i].w; k++) {
        if (v[bx + j][by + k]) {
          p[i].v[j] |= BIT(k);
        }
      }
    }

    vector<vector<int>> nx(20, vector<int>(20));
    for (int i = 0; i < 20; i++) {
      for (int j = 0; j < 20; j++) {
        nx[i][j] = v[j][19 - i];
      }
    }
    v = nx;
  }
}

vector<int> ch;
vector<int> used;
bool check() {
  int sum = 0;
  for (int i = 0; i < 20; i++) {
    sum += __builtin_popcount(~board[i]);
  }
  for (int i = 0; i < ch.size(); i++) {
    for (int j = 0; j < p[ch[i]][0].v.size(); j++) {
      sum -= __builtin_popcount(p[ch[i]][0].v[j]);
    }
  }
  return sum == 0;
}

bool can(int x, int y, Piece &pi) {
  for (int i = 0; i < pi.h; i++) {
    if (board[x + i] & (pi.v[i] << y)) {
      return false;
    }
  }
  return true;
}

bool act(int x, int y, Piece &pi) {
  for (int i = 0; i < pi.h; i++) {
    board[x + i] ^= pi.v[i] << y;
  }
}

bool ng() {
  int b[20] = {};
  for (int i = 0; i < 20; i++)
    b[i] = board[i];
  for (int i = 0; i < ch.size(); i++) {
    if (used[i])
      continue;
    for (int a = 0; a < 4; a++) {
      Piece &pi = p[ch[i]][a];
      for (int j = 0; j + pi.h <= H; j++) {
        for (int k = 0; k + pi.w <= W; k++) {
          if (can(j, k, pi)) {
            for (int l = 0; l < pi.h; l++) {
              b[j + l] |= pi.v[l] << k;
            }
          }
        }
      }
    }
  }
  for (int i = 0; i < 20; i++) {
    if (b[i] != -1)
      return true;
  }
  return false;
}

bool dfs(int cur) {
  if (cur == ch.size())
    return true;
  if (ng())
    return false;

  for (int a = 0; a < 4; a++) {
    Piece &pi = p[ch[cur]][a];
    for (int i = 0; i + pi.h <= H; i++) {
      for (int j = 0; j + pi.w <= W; j++) {
        if (can(i, j, pi)) {
          act(i, j, pi);
          used[cur] = true;
          bool f = dfs(cur + 1);
          act(i, j, pi);
          used[cur] = false;
          if (f)
            return true;
        }
      }
    }
  }
  return false;
}

int main() {
  while (scanf("%d %d", &H, &W), H) {
    memset(board, -1, sizeof(board));

    for (int i = 0; i < H; i++) {
      string str;
      cin >> str;
      for (int j = 0; j < W; j++) {
        if (str[j] == '.')
          board[i] ^= BIT(j);
      }
    }

    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
      int h, w;
      scanf("%d %d", &h, &w);
      vector<vector<int>> buf(20, vector<int>(20));
      for (int j = 0; j < h; j++) {
        for (int k = 0; k < w; k++) {
          char c;
          cin >> c;
          if (c == '#')
            buf[j][k] = 1;
        }
      }
      generate(buf, p[i]);
    }

    int m;
    scanf("%d", &m);
    for (int i = 0; i < m; i++) {
      int k;
      scanf("%d", &k);
      ch.resize(k);
      used.assign(k, 0);
      for (int j = 0; j < k; j++) {
        scanf("%d", &ch[j]);
        ch[j]--;
      }
      puts(check() && dfs(0) ? "YES" : "NO");
    }
  }
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

#define BIT(x) (1 << (x))

struct Piece {
  int h, w;
  vector<int> v;
};

int H, W;
int n;
int board[20];
Piece p[10][4];

void generate(vector<vector<int>> v, Piece p[]) {
  for (int i = 0; i < 4; i++) {
    int bx = 20, by = 20, ex = -1, ey = -1;
    for (int j = 0; j < 20; j++) {
      for (int k = 0; k < 20; k++) {
        if (v[j][k]) {
          bx = min(bx, j);
          by = min(by, k);
          ex = max(ex, j);
          ey = max(ey, k);
        }
      }
    }
    p[i].h = ex - bx + 1;
    p[i].w = ey - by + 1;
    p[i].v.assign(p[i].h, 0);
    for (int j = 0; j < p[i].h; j++) {
      for (int k = 0; k < p[i].w; k++) {
        if (v[bx + j][by + k]) {
          p[i].v[j] |= BIT(k);
        }
      }
    }

    vector<vector<int>> nx(20, vector<int>(20));
    for (int i = 0; i < 20; i++) {
      for (int j = 0; j < 20; j++) {
        nx[i][j] = v[j][19 - i];
      }
    }
    v = nx;
  }
}

vector<int> ch;
vector<int> used;
bool check() {
  int sum = 0;
  for (int i = 0; i < 20; i++) {
    sum += __builtin_popcount(~board[i]);
  }
  for (int i = 0; i < ch.size(); i++) {
    for (int j = 0; j < p[ch[i]][0].v.size(); j++) {
      sum -= __builtin_popcount(p[ch[i]][0].v[j]);
    }
  }
  return sum == 0;
}

bool can(int x, int y, Piece &pi) {
  for (int i = 0; i < pi.h; i++) {
    if (board[x + i] & (pi.v[i] << y)) {
      return false;
    }
  }
  return true;
}

bool act(int x, int y, Piece &pi) {
  for (int i = 0; i < pi.h; i++) {
    board[x + i] ^= pi.v[i] << y;
  }
}

bool dfs(int cur) {
  if (cur == H * W)
    return true;
  int x = cur / W;
  int y = cur % W;
  if (board[x] & BIT(y))
    return dfs(cur + 1);

  bool solved = true;
  for (int ii = 0; ii < ch.size(); ii++) {
    if (used[ii])
      continue;
    solved = false;

    for (int a = 0; a < 4; a++) {
      Piece &pi = p[ch[ii]][a];
      for (int i = max(x - pi.h + 1, 0); i <= min(x, H - pi.h); i++) {
        for (int j = max(y - pi.w + 1, 0); j <= min(y, W - pi.w); j++) {
          if (can(i, j, pi)) {
            act(i, j, pi);
            used[ii] = true;
            bool f = false;
            if (board[x] & BIT(y))
              f = dfs(cur + 1);
            act(i, j, pi);
            used[ii] = false;
            if (f)
              return true;
          }
        }
      }
    }
  }

  return solved;
}

int main() {
  while (scanf("%d %d", &H, &W), H) {
    memset(board, -1, sizeof(board));

    for (int i = 0; i < H; i++) {
      string str;
      cin >> str;
      for (int j = 0; j < W; j++) {
        if (str[j] == '.')
          board[i] ^= BIT(j);
      }
    }

    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
      int h, w;
      scanf("%d %d", &h, &w);
      vector<vector<int>> buf(20, vector<int>(20));
      for (int j = 0; j < h; j++) {
        for (int k = 0; k < w; k++) {
          char c;
          cin >> c;
          if (c == '#')
            buf[j][k] = 1;
        }
      }
      generate(buf, p[i]);
    }

    int m;
    scanf("%d", &m);
    for (int i = 0; i < m; i++) {
      int k;
      scanf("%d", &k);
      ch.resize(k);
      used.assign(k, 0);
      for (int j = 0; j < k; j++) {
        scanf("%d", &ch[j]);
        ch[j]--;
      }
      puts(check() && dfs(0) ? "YES" : "NO");
    }
  }
}