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

#include <iostream>
#include <stdio.h>

using namespace std;

int w[10][4], h[10][4], pn[10], pc[10], pj[10], sx[10][4], f[10], da[10][20][4],
    e[21], md[20], can[20][20][10];
int mx, my, n2;

void find() {
  int x, y, i, j, k, p;
  for (i = 0; i < n2; i++)
    for (x = 0; x < 20; x++)
      for (y = 0; y < 20; y++)
        can[y][x][pn[i]] = 0;
  for (i = 0; i < n2; i++)
    for (j = 0; j < 4; j++)
      for (y = 0; y <= my - h[pn[i]][j]; y++)
        for (x = 0; x <= mx - w[pn[i]][j]; x++) {
          for (k = 0; k < h[pn[i]][j]; k++) {
            p = da[pn[i]][k][j] * e[x];
            if ((md[y + k] + p) != (md[y + k] | p))
              break;
          }
          if (k == h[pn[i]][j])
            can[y][x][pn[i]] = 1;
        }
}

int ans(int n, int y) {
  int i, j, k, p, x;
  for (i = y; i < my; i++)
    for (j = 0; j < mx; j++)
      if ((md[i] & e[j]) == 0) {
        x = j;
        y = i;
        j = i = 99;
      }
  for (i = 0; i < n2; i++) {
    for (j = 0; j < 4; j++)
      if (can[y][x - sx[pn[i]][j]][pn[i]] == 1)
        break;
    if (f[i] == 1 || j == 4)
      continue;
    for (j = 0; j < pj[pn[i]]; j++) {
      if (x < sx[pn[i]][j] || x - sx[pn[i]][j] + w[pn[i]][j] > mx ||
          y + h[pn[i]][j] > my)
        continue;
      for (k = 0; k < h[pn[i]][j]; k++) {
        p = da[pn[i]][k][j] * e[x - sx[pn[i]][j]];
        if ((md[y + k] + p) != (md[y + k] | p))
          break;
      }
      if (k == h[pn[i]][j]) {
        if (n == 0)
          return 1;
        f[i] = 1;
        for (k = 0; k < h[pn[i]][j]; k++)
          md[y + k] += da[pn[i]][k][j] * e[x - sx[pn[i]][j]];
        p = ans(n - 1, y);
        f[i] = 0;
        for (k = 0; k < h[pn[i]][j]; k++)
          md[y + k] -= da[pn[i]][k][j] * e[x - sx[pn[i]][j]];
        if (p == 1)
          return 1;
      }
    }
  }
  return 0;
}

int main() {
  char mp[22];
  int i, j = 1, k, n, x, y, mc, p, ch[1024];
  for (i = 0; i < 21; i++) {
    e[i] = j;
    j *= 2;
  }
  while (true) {
    cin >> my >> mx;
    if (mx == 0 && my == 0)
      break;
    mc = 0;
    for (i = 0; i < my; i++) {
      cin >> mp;
      md[i] = 0;
      for (j = 0; j < mx; j++)
        if (mp[j] == '#')
          md[i] += e[j];
        else
          mc++;
    }

    cin >> n;
    for (i = 0; i < 10; i++)
      for (j = 0; j < 20; j++)
        for (k = 0; k < 4; k++)
          da[i][j][k] = 0;
    for (i = 0; i < n; i++) {
      cin >> h[i][0] >> w[i][0];
      pc[i] = 0;
      pj[i] = 4;

      for (j = 0; j < h[i][0]; j++) {
        cin >> mp;
        for (k = 0; k < w[i][0]; k++)
          if (mp[k] == '#') {
            da[i][j][0] += e[k];
            pc[i]++;
          }
      }

      for (j = 0; j < 3; j++) {
        h[i][j + 1] = w[i][j];
        w[i][j + 1] = h[i][j];
        for (y = 0; y < h[i][j]; y++)
          for (x = 0; x < w[i][j]; x++)
            if ((da[i][y][j] & e[x]) > 0)
              da[i][x][j + 1] += e[w[i][j + 1] - y - 1];
      }
      for (j = 0; j < 4; j++)
        for (k = 0; k < w[i][j]; k++)
          if ((da[i][0][j] & e[k]) > 0) {
            sx[i][j] = k;
            k = 99;
          }
      p = 0;
      for (k = 0; k < 2; k++) {
        for (y = 0; y < h[i][k]; y++)
          if (da[i][y][k] != da[i][y][k + 2])
            break;
        if (y == h[i][k])
          p++;
      }
      if (p == 2)
        pj[i] = 2;
      if (h[i][0] == h[i][1]) {
        for (y = 0; y < h[i][0]; y++)
          if (da[i][y][0] != da[i][y][1])
            break;
        if (y == h[i][0])
          pj[i] = 1;
      }
    }
    for (i = 0; i < 1024; i++)
      ch[i] = 0;
    cin >> n;
    for (i = 0; i < n; i++) {
      cin >> n2;
      p = 0;
      k = 0;
      for (j = 0; j < n2; j++) {
        cin >> pn[j];
        pn[j]--;
        p += pc[pn[j]];
        k += e[pn[j]];
      }
      find();
      if (p != mc || ch[k] == 2)
        cout << "NO" << endl;
      else if (ans(n2 - 1, 0) == 1 || ch[k] == 1) {
        cout << "YES" << endl;
        ch[k] = 1;
      } else {
        cout << "NO" << endl;
        ch[k] = 2;
      }
    }
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <iostream>
#include <stdio.h>

using namespace std;

int w[10][4], h[10][4], pn[10], pc[10], pj[10], sx[10][4], f[10], da[10][20][4],
    e[21], md[20];
int mx, my, n2;

int ans(int n, int y) {
  int i, j, k, p, x;
  for (i = y; i < my; i++)
    for (j = 0; j < mx; j++)
      if ((md[i] & e[j]) == 0) {
        x = j;
        y = i;
        j = i = 99;
      }
  for (i = 0; i < n2; i++) {
    if (f[i] == 1)
      continue;
    for (j = 0; j < 4; j++) {
      if (x < sx[pn[i]][j] || x - sx[pn[i]][j] + w[pn[i]][j] > mx ||
          y + h[pn[i]][j] > my)
        continue;
      for (k = 0; k < h[pn[i]][j]; k++) {
        p = da[pn[i]][k][j] * e[x - sx[pn[i]][j]];
        if ((md[y + k] + p) != (md[y + k] | p))
          break;
      }
      if (k == h[pn[i]][j]) {
        if (n == 0)
          return 1;
        f[i] = 1;
        for (k = 0; k < h[pn[i]][j]; k++)
          md[y + k] += da[pn[i]][k][j] * e[x - sx[pn[i]][j]];
        p = ans(n - 1, y);
        f[i] = 0;
        for (k = 0; k < h[pn[i]][j]; k++)
          md[y + k] -= da[pn[i]][k][j] * e[x - sx[pn[i]][j]];
        if (p == 1)
          return 1;
      }
    }
  }
  return 0;
}

int main() {
  char mp[22];
  int i, j = 1, k, n, x, y, mc, p, ch[1024];
  for (i = 0; i < 21; i++) {
    e[i] = j;
    j *= 2;
  }
  while (true) {
    cin >> my >> mx;
    if (mx == 0 && my == 0)
      break;
    mc = 0;
    for (i = 0; i < my; i++) {
      cin >> mp;
      md[i] = 0;
      for (j = 0; j < mx; j++)
        if (mp[j] == '#')
          md[i] += e[j];
        else
          mc++;
    }

    cin >> n;
    for (i = 0; i < 10; i++)
      for (j = 0; j < 20; j++)
        for (k = 0; k < 4; k++)
          da[i][j][k] = 0;
    for (i = 0; i < n; i++) {
      cin >> h[i][0] >> w[i][0];
      pc[i] = 0;
      pj[i] = 4;

      for (j = 0; j < h[i][0]; j++) {
        cin >> mp;
        for (k = 0; k < w[i][0]; k++)
          if (mp[k] == '#') {
            da[i][j][0] += e[k];
            pc[i]++;
          }
      }

      for (j = 0; j < 3; j++) {
        h[i][j + 1] = w[i][j];
        w[i][j + 1] = h[i][j];
        for (y = 0; y < h[i][j]; y++)
          for (x = 0; x < w[i][j]; x++)
            if ((da[i][y][j] & e[x]) > 0)
              da[i][x][j + 1] += e[w[i][j + 1] - y - 1];
      }
      for (j = 0; j < 4; j++)
        for (k = 0; k < w[i][j]; k++)
          if ((da[i][0][j] & e[k]) > 0) {
            sx[i][j] = k;
            k = 99;
          }
      p = 0;
      for (k = 0; k < 2; k++) {
        for (y = 0; y < h[i][k]; y++)
          if (da[i][y][k] != da[i][y][k + 2])
            break;
        if (y == h[i][k])
          p++;
      }
      if (p == 2)
        pj[i] = 2;
      if (h[i][0] == h[i][1]) {
        for (y = 0; y < h[i][0]; y++)
          if (da[i][y][0] != da[i][y][1])
            break;
        if (y == h[i][0])
          pj[i] = 1;
      }
    }
    for (i = 0; i < 1024; i++)
      ch[i] = 0;
    cin >> n;
    for (i = 0; i < n; i++) {
      cin >> n2;
      p = 0;
      k = 0;
      for (j = 0; j < n2; j++) {
        cin >> pn[j];
        pn[j]--;
        p += pc[pn[j]];
        k += e[pn[j]];
      }
      if (p != mc || ch[k] == 2)
        cout << "NO" << endl;
      else if (ans(n2 - 1, 0) == 1 || ch[k] == 1) {
        cout << "YES" << endl;
        ch[k] = 1;
      } else {
        cout << "NO" << endl;
        ch[k] = 2;
      }
    }
  }
  return 0;
}