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

#include <algorithm>
#include <stdio.h>
using namespace std;
int c[12][12];
int C[12];
int h[12][12][200];
int w[12][12][200];
int n[12][12][200];
int sz[12][12];
int P[12][12];
int H, W;
int valid(int a, int b, int t) {
  if (a < 0 || b < 0 || a + t > H || b + t > W)
    return 0;
  for (int i = 0; i < t; i++)
    for (int j = 0; j < t; j++)
      if (!c[a + i][b + j])
        return 0;
  return 1;
}
int lim;
int dfs(int a, int b, int v) {
  if (a == H)
    return 1;
  if (b == W)
    return dfs(a + 1, 0, v);
  if (((C[a] >> (b * 2)) & 3) != 1)
    return dfs(a, b + 1, v);
  if (v == lim)
    return 0;
  int last[12];
  for (int i = 0; i < H; i++)
    last[i] = C[i];
  for (int i = 0; i < sz[a][b]; i++) {
    for (int j = 0; j < n[a][b][i]; j++)
      C[h[a][b][i] + j] |= P[w[a][b][i]][w[a][b][i] + n[a][b][i] - 1];
    if (dfs(a, b + 1, v + 1))
      return 1;
    for (int j = 0; j < n[a][b][i]; j++)
      C[h[a][b][i] + j] = last[h[a][b][i] + j];
  }
  return 0;
}
int main() {
  int a, b;
  while (scanf("%d%d", &b, &a), a) {

    H = a;
    W = b;
    for (int i = 0; i < a; i++)
      for (int j = 0; j < b; j++)
        scanf("%d", &c[i][j]);
    for (int i = 0; i < a; i++)
      C[i] = 0;

    for (int i = 0; i < b; i++)
      for (int j = i; j < b; j++) {
        P[i][j] = 0;
        for (int k = i; k <= j; k++) {
          P[i][j] += 1 << (k * 2 + 1);
        }
        //		printf("%d %d: %d\\n",i,j,P[i][j]);
      }
    for (int i = 0; i < a; i++)
      for (int j = 0; j < b; j++)
        sz[i][j] = 0;
    for (int i = 0; i < a; i++)
      for (int j = 0; j < b; j++) {
        for (int k = 1; k <= min(a, b); k++) {
          if (valid(i, j, k) && !valid(i - 1, j - 1, k + 1) &&
              !valid(i - 1, j, k + 1) && !valid(i, j - 1, k + 1) &&
              !valid(i, j, k + 1)) {
            for (int l = 0; l < k; l++)
              for (int m = 0; m < k; m++) {
                h[i + l][j + m][sz[i + l][j + m]] = i;
                w[i + l][j + m][sz[i + l][j + m]] = j;
                n[i + l][j + m][sz[i + l][j + m]] = k;
                sz[i + l][j + m]++;
                //	printf("%d %d %d %d %d\\n",i,j,k,i+l,j+m);
              }
          }
        }
      }
    // for(int j=0;j<b;j++)for(int k=0;k<sz[i][j];k++);
    //	printf("%d %d: %d %d %d\\n",i,j,h[i][j][k],w[i][j][k],n[i][j][k]);
    int ad = 0;
    for (int i = 0; i < a; i++)
      for (int j = 0; j < b; j++) {
        int M = 0;
        for (int k = 0; k < sz[i][j]; k++)
          M = max(M, n[i][j][k]);
        if (M == 1) {
          ad++;
          c[i][j] = 0;
        }
      }
    for (int i = 0; i < a; i++)
      for (int j = 0; j < b; j++)
        C[i] += (c[i][j] << (j * 2));
    for (int i = 0;; i++) {
      lim = i;
      if (dfs(0, 0, 0)) {
        printf("%d\\n", ad + i);
        break;
      }
    }
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <stdio.h>
using namespace std;
int c[12][12];
int h[12][12][200];
int w[12][12][200];
int n[12][12][200];
int sz[12][12];
int H, W;
int valid(int a, int b, int t) {
  if (a < 0 || b < 0 || a + t > H || b + t > W)
    return 0;
  for (int i = 0; i < t; i++)
    for (int j = 0; j < t; j++)
      if (!c[a + i][b + j])
        return 0;
  return 1;
}
int lim;
int dfs(int a, int b, int v) {
  if (a == H)
    return 1;
  if (b == W)
    return dfs(a + 1, 0, v);
  if (c[a][b] != 1)
    return dfs(a, b + 1, v);
  if (v == lim)
    return 0;
  int last[12][12];
  for (int i = 0; i < H; i++)
    for (int j = 0; j < W; j++)
      last[i][j] = c[i][j];
  for (int i = 0; i < sz[a][b]; i++) {
    for (int j = 0; j < n[a][b][i]; j++)
      for (int k = 0; k < n[a][b][i]; k++) {
        c[h[a][b][i] + j][w[a][b][i] + k] = 2;
      }
    if (dfs(a, b + 1, v + 1))
      return 1;
    for (int j = 0; j < n[a][b][i]; j++)
      for (int k = 0; k < n[a][b][i]; k++)
        c[h[a][b][i] + j][w[a][b][i] + k] =
            last[h[a][b][i] + j][w[a][b][i] + k];
  }
  return 0;
}
int main() {
  int a, b;
  while (scanf("%d%d", &b, &a), a) {
    H = a;
    W = b;
    for (int i = 0; i < a; i++)
      for (int j = 0; j < b; j++)
        scanf("%d", &c[i][j]);
    for (int i = 0; i < a; i++)
      for (int j = 0; j < b; j++)
        sz[i][j] = 0;
    for (int i = 0; i < a; i++)
      for (int j = 0; j < b; j++) {
        for (int k = 1; k <= min(a, b); k++) {
          if (valid(i, j, k) && !valid(i - 1, j - 1, k + 1) &&
              !valid(i - 1, j, k + 1) && !valid(i, j - 1, k + 1) &&
              !valid(i, j, k + 1)) {
            for (int l = 0; l < k; l++)
              for (int m = 0; m < k; m++) {
                h[i + l][j + m][sz[i + l][j + m]] = i;
                w[i + l][j + m][sz[i + l][j + m]] = j;
                n[i + l][j + m][sz[i + l][j + m]] = k;
                sz[i + l][j + m]++;
                //	printf("%d %d %d %d %d\\n",i,j,k,i+l,j+m);
              }
          }
        }
      }
    // for(int j=0;j<b;j++)for(int k=0;k<sz[i][j];k++);
    //	printf("%d %d: %d %d %d\\n",i,j,h[i][j][k],w[i][j][k],n[i][j][k]);
    int ad = 0;
    for (int i = 0; i < a; i++)
      for (int j = 0; j < b; j++) {
        int M = 0;
        for (int k = 0; k < sz[i][j]; k++)
          M = max(M, n[i][j][k]);
        if (M == 1) {
          ad++;
          c[i][j] = 0;
        }
      }
    for (int i = 0;; i++) {
      lim = i;
      if (dfs(0, 0, 0)) {
        printf("%d\\n", ad + i);
        break;
      }
    }
  }
}