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

#include <iostream>
#include <map>
using namespace std;

int H, W;
class Puzzle {
public:
  int S;
  char t[20][20];

  bool operator<(const Puzzle &p) const {
    for (int i = 0; i < H; i++) {
      for (int j = 0; j < W; j++) {
        if (t[i][j] == p.t[i][j])
          continue;
        return t[i][j] < p.t[i][j];
      }
    }
    return S < p.S;
  }
};

Puzzle p;
map<Puzzle, bool> vd;

char u[40][20][20];

int h[40], w[40];
int n, m, a, b;
int v;

bool ans[2048];

void input();
void init();
void rotate(int, int);

void dfs(int, int);

void check();
bool on_check(int, int, int);

void on_tab(int, int, int);
void off_tab(int, int, int);

int main() {
  int S;
  while (cin >> H >> W) {
    if (H == 0 && W == 0)
      break;

    input();
    init();

    p.S = 0;
    dfs(0, 0);

    cin >> m;
    for (int i = 0; i < m; i++) {
      cin >> a;
      S = 0;
      for (int j = 0; j < a; j++) {
        cin >> v;
        v--;
        S += (1 << v);
      }

      if (ans[S])
        cout << "YES" << endl;
      else
        cout << "NO" << endl;
    }
  }
  return 0;
}

void dfs(int y, int x) {

  int tmp = p.S;

  bool flg = true;

  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      if (p.t[i][j] != '#')
        flg = false;
    }
  }
  if (flg) {
    ans[p.S] = true;
    return;
  }

  vd[p] = true;

  for (int i = 0; i < n; i++) {
    if ((p.S >> i) & 1 == 1)
      continue;
    for (int j = 0; j < 4; j++) {

      if (on_check(y, x, 4 * i + j) == false)
        continue;

      p.S += (1 << i);

      on_tab(y, x, 4 * i + j);

      if (vd[p] == false)
        dfs(y, x);

      off_tab(y, x, 4 * i + j);

      p.S = tmp;
    }
  }

  if (p.t[y][x] == '#')
    dfs((x + 1 == W ? y + 1 : y), (x + 1 == W ? 0 : x + 1));
}

void rotate(int a, int b) {
  for (int i = 0; i < h[a]; i++) {
    for (int j = 0; j < w[a]; j++) {
      u[a][i][j] = u[b][j][h[a] - i - 1];
    }
  }
}

void init() {
  vd.clear();
  for (int i = 0; i < 2048; i++)
    ans[i] = false;
}

void input() {
  for (int i = 0; i < 20; i++)
    for (int j = 0; j < 20; j++)
      p.t[i][j] = '.';

  string str;
  for (int i = 0; i < H; i++) {
    cin >> str;
    for (int j = 0; j < W; j++) {
      p.t[i][j] = str[j];
    }
  }
  cin >> n;
  for (int k = 0; k < n; k++) {
    cin >> h[k * 4] >> w[k * 4];
    for (int i = 0; i < h[k * 4]; i++) {
      cin >> str;
      for (int j = 0; j < w[k * 4]; j++) {
        u[k * 4][i][j] = str[j];
      }
    }
    for (int i = 1; i < 4; i++) {
      h[k * 4 + i] = w[k * 4 + i - 1];
      w[k * 4 + i] = h[k * 4 + i - 1];
      rotate(k * 4 + i, k * 4 + i - 1);
    }
  }
}

bool on_check(int y, int x, int A) {
  if (y + h[A] > H || x + w[A] > W)
    return false;
  for (int i = y; i < y + h[A]; i++) {
    for (int j = x; j < x + w[A]; j++) {
      if (u[A][i - y][j - x] == '#' && p.t[i][j] == '#')
        return false;
    }
  }
  return true;
}

void on_tab(int y, int x, int A) {
  for (int i = y; i < y + h[A]; i++) {
    for (int j = x; j < x + w[A]; j++) {
      if (u[A][i - y][j - x] == '#')
        p.t[i][j] = '#';
    }
  }
}

void off_tab(int y, int x, int A) {
  for (int i = y; i < y + h[A]; i++) {
    for (int j = x; j < x + w[A]; j++) {
      if (u[A][i - y][j - x] == '#')
        p.t[i][j] = '.';
    }
  }
}

Error: TLE

Fixed submission:

#include <iostream>
#include <vector>
using namespace std;
int H, W;
char t[20][20];

char u[40][20][20];

int h[40], w[40];
int n, m, a, b;

int v[10];

bool ans[2048];

void input();
void init();
void rotate(int, int);

void dfs(int, int, int);

bool check_table[40][20][20];
void check();
bool on_check(int, int, int);

void on_tab(int, int, int);
void off_tab(int, int, int);

int main() {
  int S;
  while (cin >> H >> W) {
    if (H == 0 && W == 0)
      break;

    input();
    init();

    dfs(0, 0, 0);

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

      if (ans[S])
        cout << "YES" << endl;
      else
        cout << "NO" << endl;
    }
  }
  return 0;
}

bool array[2048][20][20];

void dfs(int S, int y, int x) {

  int next = S;
  if (y == H) {
    ans[S] = true;
    return;
  }

  if (t[y][x] == '#')
    dfs(S, (x + 1 == W ? y + 1 : y), (x + 1 == W ? 0 : x + 1));

  for (int i = 0; i < n; i++) {
    if ((S >> i) & 1 == 1)
      continue;
    for (int j = 0; j < 4; j++) {
      if (check_table[4 * i + j][y][x] == false)
        continue;
      if (on_check(y, x, 4 * i + j) == false)
        continue;

      next = S + (1 << i);

      on_tab(y, x, 4 * i + j);
      dfs(next, y, x);
      off_tab(y, x, 4 * i + j);
    }
  }
}

void rotate(int a, int b) {
  for (int i = 0; i < h[a]; i++) {
    for (int j = 0; j < w[a]; j++) {
      u[a][i][j] = u[b][j][h[a] - i - 1];
    }
  }
}

void init() {
  for (int i = 0; i < 2048; i++) {
    ans[i] = false;
    for (int j = 0; j < 20; j++) {
      for (int k = 0; k < 20; k++) {
        array[i][j][k] = false;
      }
    }
  }

  for (int i = 0; i < n * 4; i++) {
    for (int j = 0; j < H; j++) {
      for (int k = 0; k < W; k++) {
        check_table[i][j][k] = on_check(j, k, i);
      }
    }
  }
}

void input() {
  string str;
  for (int i = 0; i < H; i++) {
    cin >> str;
    for (int j = 0; j < W; j++) {
      t[i][j] = str[j];
    }
  }
  cin >> n;
  for (int k = 0; k < n; k++) {
    cin >> h[k * 4] >> w[k * 4];
    for (int i = 0; i < h[k * 4]; i++) {
      cin >> str;
      for (int j = 0; j < w[k * 4]; j++) {
        u[k * 4][i][j] = str[j];
      }
    }
    for (int i = 1; i < 4; i++) {
      h[k * 4 + i] = w[k * 4 + i - 1];
      w[k * 4 + i] = h[k * 4 + i - 1];
      rotate(k * 4 + i, k * 4 + i - 1);
    }
  }
}

bool on_check(int y, int x, int A) {
  if (y + h[A] > H || x + w[A] > W)
    return false;
  for (int i = y; i < y + h[A]; i++) {
    for (int j = x; j < x + w[A]; j++) {
      if (u[A][i - y][j - x] == '#' && t[i][j] == '#')
        return false;
    }
  }
  return true;
}

void on_tab(int y, int x, int A) {
  for (int i = y; i < y + h[A]; i++) {
    for (int j = x; j < x + w[A]; j++) {
      if (u[A][i - y][j - x] == '#')
        t[i][j] = '#';
    }
  }
}

void off_tab(int y, int x, int A) {
  for (int i = y; i < y + h[A]; i++) {
    for (int j = x; j < x + w[A]; j++) {
      if (u[A][i - y][j - x] == '#')
        t[i][j] = '.';
    }
  }
}