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

#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <time.h>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

struct Info {
  short table[10][10], num;
};

int W, H, ans, POW[11];
int first_table[10][10], max_size[10][10];

bool rangeCheck(int row, int col) {
  if (row >= 0 && row <= H - 1 && col >= 0 && col <= W - 1)
    return true;
  else {
    return false;
  }
}

void recursive(Info info, int base_row, int base_col) {

  if (info.num == ans)
    return;

  if (base_row == H) {
    ans = info.num;
    return;
  }

  if (info.table[base_row][base_col] == -1) {

    if (base_col == W - 1) {
      recursive(info, base_row + 1, 0);
    } else {
      recursive(info, base_row, base_col + 1);
    }
    return;
  }

  int new_num = 0;
  for (int i = 0; i < max_size[base_row][base_col]; i++) {
    for (int k = 0; k < max_size[base_row][base_col]; k++) {
      if (info.table[base_row + i][base_col + k] == 0) {
        new_num++;
        break;
      }
    }
    if (new_num != 0)
      break;
  }

  if (new_num == 0) {

    if (base_col != W - 1) {
      recursive(info, base_row, base_col + 1);
    } else {
      recursive(info, base_row + 1, 0);
    }
  } else {

    if (info.table[base_row][base_col] != 0) {

      if (base_col != W - 1) {
        recursive(info, base_row, base_col + 1);
      } else {
        recursive(info, base_row + 1, 0);
      }
    }

    for (int i = 0; i < max_size[base_row][base_col]; i++) {
      for (int k = 0; k < max_size[base_row][base_col]; k++) {
        info.table[base_row + i][base_col + k]++;
      }
    }

    int must_add = 0;
    bool FLG = false;

    for (int row = base_row; row <= base_row; row++) {
      for (int col = base_col; col < W; col++) {
        if (info.table[row][col] == 0 && first_table[row][col] > 1) {
          FLG = true;
          goto SHISHIMARU;
        }
      }
    }

    for (int row = base_row + 1; row < H; row++) {
      for (int col = 0; col < W; col++) {
        if (info.table[row][col] == 0 && first_table[row][col] > 1) {
          FLG = true;
          goto SHISHIMARU;
        }
      }
    }

  SHISHIMARU:

    if (FLG)
      must_add++;

    info.num++;

    if (info.num + must_add < ans) {
      if (base_col != W - 1) {
        recursive(info, base_row, base_col + 1);
      } else {
        recursive(info, base_row + 1, 0);
      }
    }
  }
}

void func() {

  for (int row = 0; row < H; row++) {
    for (int col = 0; col < W; col++) {
      scanf("%d", &first_table[row][col]);
      first_table[row][col] -= 1;
    }
  }

  bool FLG;
  int size;

  for (int row = 0; row < H; row++) {
    for (int col = 0; col < W; col++) {
      if (first_table[row][col] == -1) {
        max_size[row][col] = 0;
      } else {
        size = 1;

        FLG = true;

        while (true) {
          for (int i = 0; i < size; i++) {
            for (int k = 0; k < size; k++) {
              if (rangeCheck(row + i, col + k) == false ||
                  first_table[row + i][col + k] == -1) {
                FLG = false;
                break;
              }
            }
            if (!FLG)
              break;
          }
          if (!FLG) {
            size -= 1;
            break;
          }
          size++;
        }

        max_size[row][col] = size;

        for (int calc_size = 1; calc_size <= size; calc_size++) {
          for (int i = 0; i < calc_size; i++) {
            for (int k = 0; k < size; k++) {
              first_table[row + i][col + k]++;
            }
          }
        }
      }
    }
  }

  Info start;
  start.num = 0;

  for (int row = 0; row < H; row++) {
    for (int col = 0; col < W; col++) {
      if (first_table[row][col] == -1) {
        start.table[row][col] = -1;
      } else {
        if (first_table[row][col] == 1) {
          start.num++;
          start.table[row][col] = 1;
        } else {
          start.table[row][col] = 0;
        }
      }
    }
  }

  ans = BIG_NUM;

  recursive(start, 0, 0);

  printf("%d\\n", ans);
}

int main() {

  for (int i = 0; i < 11; i++)
    POW[i] = pow(2, i);

  while (true) {
    scanf("%d %d", &W, &H);
    if (W == 0 && H == 0)
      break;

    func();
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <time.h>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

struct Info {
  short table[10][10], num;
};

int W, H, ans, POW[11];
short first_table[10][10], max_size[10][10];

bool rangeCheck(int row, int col) {
  if (row >= 0 && row <= H - 1 && col >= 0 && col <= W - 1)
    return true;
  else {
    return false;
  }
}

void recursive(Info info, int base_row, int base_col, int pre_must_add) {

  if (info.num == ans)
    return;

  if (base_row == H) {
    ans = info.num;
    return;
  }

  if (info.table[base_row][base_col] == -1) {

    if (base_col == W - 1) {
      recursive(info, base_row + 1, 0, pre_must_add);
    } else {
      recursive(info, base_row, base_col + 1, pre_must_add);
    }
    return;
  }

  int new_num = 0;
  int add = max_size[base_row][base_col] - 1;
  if (info.table[base_row + add][base_col + add] == 0 ||
      info.table[base_row + add][base_col + add - 1] == 0) {
    new_num = 1;
  }

  if (new_num == 0) {

    if (base_col != W - 1) {
      recursive(info, base_row, base_col + 1, pre_must_add);
    } else {
      recursive(info, base_row + 1, 0, pre_must_add);
    }
  } else {

    if (info.table[base_row][base_col] != 0) {

      if (base_col != W - 1) {
        recursive(info, base_row, base_col + 1, pre_must_add);
      } else {
        recursive(info, base_row + 1, 0, pre_must_add);
      }
    }

    for (int i = 0; i < max_size[base_row][base_col]; i++) {
      for (int k = 0; k < max_size[base_row][base_col]; k++) {
        info.table[base_row + i][base_col + k]++;
      }
    }

    int must_add = 0;
    bool FLG = false;

    for (int row = base_row; row <= base_row; row++) {
      for (int col = base_col + add; col < W; col++) {
        if (info.table[row][col] == 0 && first_table[row][col] == 1) {
          must_add++;
        } else if (info.table[row][col] == 0 && first_table[row][col] > 1) {
          FLG = true;
        }
      }
    }

    for (int row = base_row + 1; row < H; row++) {
      for (int col = 0; col < W; col++) {
        if (info.table[row][col] == 0 && first_table[row][col] == 1) {
          must_add++;
        } else if (info.table[row][col] == 0 && first_table[row][col] > 1) {
          FLG = true;
        }
      }
    }

    if (FLG)
      must_add++;

    info.num++;

    if (info.num + must_add < ans) {
      if (base_col != W - 1) {
        recursive(info, base_row, base_col + 1, must_add);
      } else {
        recursive(info, base_row + 1, 0, must_add);
      }
    }
  }
}

void func() {

  for (int row = 0; row < H; row++) {
    for (int col = 0; col < W; col++) {
      scanf("%d", &first_table[row][col]);
      first_table[row][col] -= 1;
    }
  }

  bool FLG;
  int size;

  for (int row = 0; row < H; row++) {
    for (int col = 0; col < W; col++) {
      if (first_table[row][col] == -1) {
        max_size[row][col] = 0;
      } else {
        size = 1;

        FLG = true;

        while (true) {
          for (int i = 0; i < size; i++) {
            for (int k = 0; k < size; k++) {
              if (rangeCheck(row + i, col + k) == false ||
                  first_table[row + i][col + k] == -1) {
                FLG = false;
                break;
              }
            }
            if (!FLG)
              break;
          }
          if (!FLG) {
            size -= 1;
            break;
          }
          size++;
        }

        max_size[row][col] = size;

        for (int calc_size = 1; calc_size <= size; calc_size++) {
          for (int i = 0; i < calc_size; i++) {
            for (int k = 0; k < size; k++) {
              first_table[row + i][col + k]++;
            }
          }
        }
      }
    }
  }

  Info start;
  start.num = 0;
  int pre_must_add = 0;
  FLG = false;

  for (int row = 0; row < H; row++) {
    for (int col = 0; col < W; col++) {
      if (first_table[row][col] == -1) {
        start.table[row][col] = -1;
      } else {
        if (first_table[row][col] == 1) {
          pre_must_add++;
        } else {
          FLG = true;
        }
        start.table[row][col] = 0;
      }
    }
  }

  if (FLG)
    pre_must_add++;

  ans = BIG_NUM;

  recursive(start, 0, 0, pre_must_add);

  printf("%d\\n", ans);
}

int main() {

  for (int i = 0; i < 11; i++)
    POW[i] = pow(2, i);

  while (true) {
    scanf("%d %d", &W, &H);
    if (W == 0 && H == 0)
      break;

    func();
  }

  return 0;
}