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

#include <algorithm>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <functional>
#include <iostream>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#ifdef _MSC_VER
#define __typeof__ decltype

template <class T> int __builtin_popcount(T n) {
  return n ? 1 + __builtin_popcount(n & (n - 1)) : 0;
}
#endif

#define foreach(it, c)                                                         \\
  for (__typeof__((c).begin()) it = (c).begin(); it != (c).end(); ++it)
#define all(c) (c).begin(), (c).end()
#define rall(c) (c).rbegin(), (c).rend()
#define popcount __builtin_popcount

const double EPS = 1e-8;
typedef long long ll;
typedef pair<int, int> pint;

int w, h, n;
pint info[16];
int land[10][10], ans_land[10][10];
pint sign_pos[16];

bool can_put(int left, int top, int width, int height, int b) {
  int right = left + width - 1;
  int bottom = top + height - 1;
  if (left < 0 || top < 0 || right >= w || bottom >= h)
    return false;

  for (int y = top; y <= bottom; ++y)
    for (int x = left; x <= right; ++x)
      if (land[y][x] != 0 && land[y][x] != b)
        return false;
  return true;
}
void put(int left, int top, int width, int height, int b) {
  int right = left + width - 1;
  int bottom = top + height - 1;

  for (int y = top; y <= bottom; ++y)
    for (int x = left; x <= right; ++x)
      land[y][x] = b;
}
bool ok() {
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x)
      if (land[y][x] == 0)
        return false;
  return true;
}
int dfs(int depth) {
  if (depth == n) {
    if (ok()) {
      memcpy(ans_land, land, sizeof(ans_land));
      return 1;
    } else
      return 0;
  }

  int res = 0;

  int b = info[depth].second;
  int k = info[depth].first;
  int sx = sign_pos[b].first;
  int sy = sign_pos[b].second;
  for (int height = 1; height <= k; ++height) {
    if (k % height)
      continue;
    int width = k / height;
    for (int y = sy - height - 1; y <= sy; ++y) {
      for (int x = sx - width - 1; x <= sx; ++x) {
        if (can_put(x, y, width, height, b)) {
          put(x, y, width, height, b);
          res += dfs(depth + 1);
          put(x, y, width, height, 0);
          land[sy][sx] = b;

          if (res > 1)
            return 2;
        }
      }
    }
  }

  return res;
}
int main() {
  while (scanf("%d%d%d", &w, &h, &n), w | h | n) {
    memset(info, 0, sizeof(info));
    for (int i = 0; i < n; ++i) {
      int b, k;
      scanf("%d%d", &b, &k);
      info[i] = pint(k, b);
    }
    sort(info, info + n, greater<pint>());

    for (int y = 0; y < h; ++y)
      for (int x = 0; x < w; ++x)
        scanf("%d", &land[y][x]);
    for (int y = 0; y < h; ++y)
      for (int x = 0; x < w; ++x)
        if (land[y][x])
          sign_pos[land[y][x]] = pint(x, y);

    if (dfs(0) == 1) {
      for (int y = 0; y < h; ++y) {
        for (int x = 0; x < w - 1; ++x)
          printf("%d ", ans_land[y][x]);
        printf("%d\\n", ans_land[y][w - 1]);
      }
    } else
      puts("NA");
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <functional>
#include <iostream>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#ifdef _MSC_VER
#define __typeof__ decltype

template <class T> int __builtin_popcount(T n) {
  return n ? 1 + __builtin_popcount(n & (n - 1)) : 0;
}
#endif

#define foreach(it, c)                                                         \\
  for (__typeof__((c).begin()) it = (c).begin(); it != (c).end(); ++it)
#define all(c) (c).begin(), (c).end()
#define rall(c) (c).rbegin(), (c).rend()
#define popcount __builtin_popcount

const double EPS = 1e-8;
typedef long long ll;
typedef pair<int, int> pint;

int w, h, n;
pint info[16];
int land[10][10], ans_land[10][10];
pint sign_pos[16];

bool can_put(int left, int top, int width, int height, int b) {
  int right = left + width - 1;
  int bottom = top + height - 1;
  if (left < 0 || top < 0 || right >= w || bottom >= h)
    return false;

  for (int y = top; y <= bottom; ++y)
    for (int x = left; x <= right; ++x)
      if (land[y][x] != 0 && land[y][x] != b)
        return false;
  return true;
}
void put(int left, int top, int width, int height, int b) {
  int right = left + width - 1;
  int bottom = top + height - 1;

  for (int y = top; y <= bottom; ++y)
    for (int x = left; x <= right; ++x)
      land[y][x] = b;
}
bool ok() {
  for (int y = 0; y < h; ++y)
    for (int x = 0; x < w; ++x)
      if (land[y][x] == 0)
        return false;
  return true;
}
int dfs(int depth) {
  if (depth == n) {
    if (ok()) {
      memcpy(ans_land, land, sizeof(ans_land));
      return 1;
    } else
      return 0;
  }

  int res = 0;

  int b = info[depth].first;
  int k = info[depth].second;
  int sx = sign_pos[b].first;
  int sy = sign_pos[b].second;
  for (int height = 1; height <= k; ++height) {
    if (k % height)
      continue;
    int width = k / height;
    for (int y = sy - height - 1; y <= sy; ++y) {
      for (int x = sx - width - 1; x <= sx; ++x) {
        if (can_put(x, y, width, height, b)) {
          put(x, y, width, height, b);
          res += dfs(depth + 1);
          put(x, y, width, height, 0);
          land[sy][sx] = b;

          if (res > 1)
            return 2;
        }
      }
    }
  }

  return res;
}
int main() {
  while (scanf("%d%d%d", &w, &h, &n), w | h | n) {
    memset(info, 0, sizeof(info));
    for (int i = 0; i < n; ++i) {
      int b, k;
      scanf("%d%d", &b, &k);
      info[i] = pint(b, k);
    }
    sort(info, info + n, greater<pint>());

    for (int y = 0; y < h; ++y)
      for (int x = 0; x < w; ++x)
        scanf("%d", &land[y][x]);
    for (int y = 0; y < h; ++y)
      for (int x = 0; x < w; ++x)
        if (land[y][x])
          sign_pos[land[y][x]] = pint(x, y);

    if (dfs(0) == 1) {
      for (int y = 0; y < h; ++y) {
        for (int x = 0; x < w - 1; ++x)
          printf("%d ", ans_land[y][x]);
        printf("%d\\n", ans_land[y][w - 1]);
      }
    } else
      puts("NA");
  }

  return 0;
}